spring boot 2.x spring cloud Greenwich.SR1 @SpringCloudApplication注解、@EnableDiscoveryClient注解详解

spring boot 2.x spring cloud Greenwich.SR1 @SpringCloudApplication注解、@EnableDiscoveryClient注解详解

@SpringCloudApplication注解

最近再看springcloud的小部分源码的时候,发现了一个有意思的注解@SpringCloudApplication,我们先看下注解的内容

/**
 * @author Spencer Gibb
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {

}

可以看到,这个注解,是由三个注解组合而成@SpringBootApplication@EnableDiscoveryClient@EnableCircuitBreaker;我们可以直接使用这个注解,来使用springcloud的一些组合功能,比如断路器(hystrix)以及客户端(服务的提供者)注册到注册中心;

1.1、@SpringBootApplication注解

这个注解,大家都很熟悉了,就不解释了,详细的,也可以参看《springboot2.0 主程序类@SpringBootApplication详解,@SpringBootConfiguration,@EnableAutoConfiguration》

1.2、@EnableDiscoveryClient注解

这个注解的作用,开启客户端的注册功能,把当前应用,注册到注册中心中;@EnableEurekaClient注解,只支持eureka作为注册中心,而@EnableDiscoveryClient,支持其他的注册中心(consul,eureka等);

先看下这个注解的定义内容

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {

	/**
	 * If true, the ServiceRegistry will automatically register the local server.
	 * @return - {@code true} if you want to automatically register.
	 */
	boolean autoRegister() default true;

}

这个注解中,有个autoRegister属性,默认为true;,表示是否自动这个服务本地服务;

注解中,还通过@Import注解,为容器中导入了EnableDiscoveryClientImportSelector类;关于@Import注解,还有不熟悉的,可以参看《spring注解 @Import的使用,ImportSelector接口,ImportBeanDefinitionRegistrar接口》

我们详细看下,EnableDiscoveryClientImportSelector类中(主要代码),为容器导入了什么组件;

@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class EnableDiscoveryClientImportSelector
		extends SpringFactoryImportSelector<EnableDiscoveryClient> {

	@Override
	public String[] selectImports(AnnotationMetadata metadata) {
    //获取父级中为容器导入的组件的数组,默认为空数组
		String[] imports = super.selectImports(metadata);
		//获取注解的详细
		AnnotationAttributes attributes = AnnotationAttributes.fromMap(
				metadata.getAnnotationAttributes(getAnnotationClass().getName(), true));
		//获取注解中,	boolean autoRegister() default true;的属性,默认就是true
		boolean autoRegister = attributes.getBoolean("autoRegister");

		if (autoRegister) {
      //为组件中新增AutoServiceRegistrationConfiguration这个自动装配类
			List<String> importsList = new ArrayList<>(Arrays.asList(imports));
			importsList.add(
			"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
			imports = importsList.toArray(new String[0]);
		}
		else {
      //如果为flase,为容器中,
      //设置spring.cloud.service-registry.auto-registration.enabled的属性为true
      //类型在yaml中,设置这个属性为true
			Environment env = getEnvironment();
			if (ConfigurableEnvironment.class.isInstance(env)) {
				ConfigurableEnvironment configEnv = (ConfigurableEnvironment) env;
				LinkedHashMap<String, Object> map = new LinkedHashMap<>();
				map.put("spring.cloud.service-registry.auto-registration.enabled", false);
				MapPropertySource propertySource = new MapPropertySource(
						"springCloudDiscoveryClient", map);
				configEnv.getPropertySources().addLast(propertySource);
			}

		}
	//返回注入的组件,也就是上面的AutoServiceRegistrationConfiguration配置类
		return imports;
	}

根据上面的代码,可以知道,使用@EnableDiscoveryClient注解,为容器中,注入了一个org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration的配置类,这个类,在spring-cloud-commons-2.1.1.RELEASE.jar中的对应包下,我看下这个配置类,又为容器中,注入了什么内容

/**
 * @author Spencer Gibb
 */
@Configuration
@EnableConfigurationProperties(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
public class AutoServiceRegistrationConfiguration {

}

可以看到,没有为容器中注入组件,是一个空的配置类;如果为容器中注入一个空的配置类,是不是没有意义?会不会是其他的组件(配置类)在使用之前,必须要依赖这个组件,我直接搜索了一下,调用AutoServiceRegistrationConfiguration这个类的地方;还真搜索到了2个地方;如图所示:

第二个就是注解对象本身,不在细说;

我们看第一个,调用的配置类org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration

@Configuration
@Import(AutoServiceRegistrationConfiguration.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
public class AutoServiceRegistrationAutoConfiguration {

	@Autowired(required = false)
	private AutoServiceRegistration autoServiceRegistration;

	@Autowired
	private AutoServiceRegistrationProperties properties;

	@PostConstruct
	protected void init() {
		if (this.autoServiceRegistration == null && this.properties.isFailFast()) {
			throw new IllegalStateException("Auto Service Registration has "
					+ "been requested, but there is no AutoServiceRegistration bean");
		}
	}

}

这个配置类中,也使用了@Import导入这个AutoServiceRegistrationConfiguration;配置类中,并没有注入其他的组件,只是一个默认的初始化方法;

我们再看下,什么地方调用默认自动装配了AutoServiceRegistrationAutoConfiguration;我们都知道,默认装配类,一般都是写到到spring.factories,我们看下文件的内容

这个类,被springboot自动装配了;

所以说,理论上,我们是不需要加@EnableDiscoveryClient注解的,跟不需要加@EnableEurekaClient注解一样,也会被注册到注册中心中;

1.3、@EnableCircuitBreaker注解

这个注解,是断路器的注解,开启断路器,另外开启断路器的注解@EnableHystrix,我们先看下注解的定义

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {

}

可以看到,@EnableHystrix注解,本质上就是使用的@EnableCircuitBreaker注解;

原创文章 83 获赞 155 访问量 36万+

猜你喜欢

转载自blog.csdn.net/qq_28410283/article/details/103977423