聊聊springcloud的featuresEndpoint
序
本文主要研究下springcloud的featuresEndpoint
/actuator/features
{ "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
@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
@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
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
@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
相关推荐
yupi0 2020-10-10
spring 2020-08-18
编程点滴 2020-07-29
幸运小侯子 2020-07-05
itjavashuai 2020-07-04
qingjiuquan 2020-06-29
shushan 2020-06-25
小鱿鱼 2020-06-22
咻pur慢 2020-06-18
melonjj 2020-06-17
qingjiuquan 2020-06-13
neweastsun 2020-06-05
小鱿鱼 2020-06-05
mxcsdn 2020-05-31
吾日五省我身 2020-05-27
牧场SZShepherd 2020-05-27
sweetgirl0 2020-05-14