sequence

This article focuses on featuresEndpoint of springcloud

/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": []}Copy the code

CommonsClientAutoConfiguration

. Spring – the cloud – Commons – 2.0.0 RC1 – sources. The 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() {
			returnnew FeaturesEndpoint(this.hasFeatures); }}}Copy the code

There is an ActuatorConfiguration to register featuresEndpoint

FeaturesEndpoint

. Spring – the cloud – Commons – 2.0.0 RC1 – sources. The 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); }}}returnfeatures; } 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())); } / /... }Copy the code

The hasFeaturesList is used to assemble two classes of features, abstractFeatures and namedFeatures

HasFeatures

. Spring – the cloud – Commons – 2.0.0 RC1 – sources. The 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) {
		returnnew 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() {
		returnthis.namedFeatures; }}Copy the code

There are two classes of features defined here, one is abstractFeatures and one is namedFeatures

HasFeatures instance

Spring – the cloud – netflix – eureka – the client – 2.0.0. RC1 – sources. The 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); } / /... }Copy the code

For example, eureka’s client registers a namedFeature named Eureka Client

summary

Springcloud provides featuresEndpoint, which allows you to view some of the startup features to understand the characteristics of your system.

doc

  • spring-cloud.html#enabled-features