前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊springcloud的featuresEndpoint

聊聊springcloud的featuresEndpoint

作者头像
code4it
发布2018-09-17 16:12:35
9420
发布2018-09-17 16:12:35
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究下springcloud的featuresEndpoint

/actuator/features

代码语言:javascript
复制
{
  "enabled": [
    {
      "type": "com.netflix.discovery.EurekaClient",
      "name": "Eureka Client",
      "version": "1.8.8",
      "vendor": null
    },
    {
      "type": "org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient",
      "name": "DiscoveryClient",
      "version": "2.0.0.RC1",
      "vendor": "Pivotal Software, Inc."
    },
    {
      "type": "org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient",
      "name": "LoadBalancerClient",
      "version": "2.0.0.RC1",
      "vendor": "Pivotal Software, Inc."
    },
    {
      "type": "com.netflix.ribbon.Ribbon",
      "name": "Ribbon",
      "version": "2.2.5",
      "vendor": null
    },
    {
      "type": "feign.Feign",
      "name": "Feign",
      "version": null,
      "vendor": null
    }
  ],
  "disabled": []
}

CommonsClientAutoConfiguration

spring-cloud-commons-2.0.0.RC1-sources.jar!/org/springframework/cloud/client/CommonsClientAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@AutoConfigureOrder(0)
public class CommonsClientAutoConfiguration {

    @Configuration
    @EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class)
    @ConditionalOnClass(HealthIndicator.class)
    @ConditionalOnBean(DiscoveryClient.class)
    @ConditionalOnProperty(value = "spring.cloud.discovery.enabled", matchIfMissing = true)
    protected static class DiscoveryLoadBalancerConfiguration {
        @Bean
        @ConditionalOnProperty(value = "spring.cloud.discovery.client.health-indicator.enabled", matchIfMissing = true)
        public DiscoveryClientHealthIndicator discoveryClientHealthIndicator(
                DiscoveryClient discoveryClient, DiscoveryClientHealthIndicatorProperties properties) {
            return new DiscoveryClientHealthIndicator(discoveryClient, properties);
        }

        @Bean
        @ConditionalOnProperty(value = "spring.cloud.discovery.client.composite-indicator.enabled", matchIfMissing = true)
        @ConditionalOnBean(DiscoveryHealthIndicator.class)
        public DiscoveryCompositeHealthIndicator discoveryCompositeHealthIndicator(
                HealthAggregator aggregator, List<DiscoveryHealthIndicator> indicators) {
            return new DiscoveryCompositeHealthIndicator(aggregator, indicators);
        }

        @Bean
        public HasFeatures commonsFeatures() {
            return HasFeatures.abstractFeatures(DiscoveryClient.class,
                    LoadBalancerClient.class);
        }
    }

    @Configuration
    @ConditionalOnClass(Endpoint.class)
    @ConditionalOnProperty(value = "spring.cloud.features.enabled", matchIfMissing = true)
    protected static class ActuatorConfiguration {
        @Autowired(required = false)
        private List<HasFeatures> hasFeatures = new ArrayList<>();

        @Bean
        @ConditionalOnEnabledEndpoint
        public FeaturesEndpoint featuresEndpoint() {
            return new FeaturesEndpoint(this.hasFeatures);
        }
    }

}

这里有一个ActuatorConfiguration,用来注册featuresEndpoint

FeaturesEndpoint

spring-cloud-commons-2.0.0.RC1-sources.jar!/org/springframework/cloud/client/actuator/FeaturesEndpoint.java

代码语言:javascript
复制
@Endpoint(id = "features")
public class FeaturesEndpoint
        implements ApplicationContextAware {

    private final List<HasFeatures> hasFeaturesList;
    private ApplicationContext context;

    public FeaturesEndpoint(List<HasFeatures> hasFeaturesList) {
        this.hasFeaturesList = hasFeaturesList;
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.context = context;
    }

    @ReadOperation
    public Features features() {
        Features features = new Features();

        for (HasFeatures hasFeatures : this.hasFeaturesList) {
            List<Class<?>> abstractFeatures = hasFeatures.getAbstractFeatures();
            if (abstractFeatures != null) {
                for (Class<?> clazz : abstractFeatures) {
                    addAbstractFeature(features, clazz);
                }
            }

            List<NamedFeature> namedFeatures = hasFeatures.getNamedFeatures();
            if (namedFeatures != null) {
                for (NamedFeature namedFeature : namedFeatures) {
                    addFeature(features, namedFeature);
                }
            }
        }

        return features;
    }

    private void addAbstractFeature(Features features, Class<?> type) {
        String featureName = type.getSimpleName();
        try {
            Object bean = this.context.getBean(type);
            Class<?> beanClass = bean.getClass();
            addFeature(features, new NamedFeature(featureName, beanClass));
        }
        catch (NoSuchBeanDefinitionException e) {
            features.getDisabled().add(featureName);
        }
    }

    private void addFeature(Features features, NamedFeature feature) {
        Class<?> type = feature.getType();
        features.getEnabled()
                .add(new Feature(feature.getName(), type.getCanonicalName(),
                        type.getPackage().getImplementationVersion(),
                        type.getPackage().getImplementationVendor()));
    }
    //......
}

这里通过hasFeaturesList来组装两类features,一类是abstractFeatures,另外一类是namedFeatures

HasFeatures

spring-cloud-commons-2.0.0.RC1-sources.jar!/org/springframework/cloud/client/actuator/HasFeatures.java

代码语言:javascript
复制
public class HasFeatures {

    private final List<Class<?>> abstractFeatures = new ArrayList<>();

    private final List<NamedFeature> namedFeatures = new ArrayList<>();

    public static HasFeatures abstractFeatures(Class<?>... abstractFeatures) {
        return new HasFeatures(Arrays.asList(abstractFeatures),
                Collections.<NamedFeature> emptyList());
    }

    public static HasFeatures namedFeatures(NamedFeature... namedFeatures) {
        return new HasFeatures(Collections.<Class<?>> emptyList(),
                Arrays.asList(namedFeatures));
    }

    public static HasFeatures namedFeature(String name, Class<?> type) {
        return namedFeatures(new NamedFeature(name, type));
    }

    public static HasFeatures namedFeatures(String name1, Class<?> type1, String name2,
            Class<?> type2) {
        return namedFeatures(new NamedFeature(name1, type1),
                new NamedFeature(name2, type2));
    }

    public HasFeatures(List<Class<?>> abstractFeatures,
            List<NamedFeature> namedFeatures) {
        this.abstractFeatures.addAll(abstractFeatures);
        this.namedFeatures.addAll(namedFeatures);
    }

    public List<Class<?>> getAbstractFeatures() {
        return this.abstractFeatures;
    }

    public List<NamedFeature> getNamedFeatures() {
        return this.namedFeatures;
    }
}

这里定义了两类features,一类是abstractFeatures,一类是namedFeatures

HasFeatures实例

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@Import(DiscoveryClientOptionalArgsConfiguration.class)
@ConditionalOnBean(EurekaDiscoveryClientConfiguration.Marker.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
        CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class })
@AutoConfigureAfter(name = {"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
        "org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration",
        "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration"})
public class EurekaClientAutoConfiguration {

    private ConfigurableEnvironment env;

    public EurekaClientAutoConfiguration(ConfigurableEnvironment env) {
        this.env = env;
    }

    @Bean
    public HasFeatures eurekaFeature() {
        return HasFeatures.namedFeature("Eureka Client", EurekaClient.class);
    }
    //......
}

比如eureka的client就注册了一个名为Eureka Client的namedFeature

小结

springcloud提供的featuresEndpoint,可以方便我们查看系统启动的一些features,进而了解系统特征。

doc

  • spring-cloud.html#enabled-features
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • /actuator/features
  • CommonsClientAutoConfiguration
  • FeaturesEndpoint
  • HasFeatures
  • HasFeatures实例
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档