畅销书“Spring Cloud Alibaba微服务架构实战派(上下册)”作者。
用过Spring Cloud Alibaba或者Spring Cloud 的开发人员应该都知道注解@EnableDiscoveryClient,但是,在实际的项目开发中,估计很多开发人员都很少会去关注它,因为它太不起眼了。
很多开发会觉得Spring Cloud Alibaba不是很简单吗?我百度一下就可以搜索到一大堆原理分析及项目Demo,但是你是否真的从系统思维的角度去分析Spring Cloud Alibaba存在的价值。
笔者一般都会这么看待这个问题。
我会打开源码,找到这个注解@EnableDiscoveryClient,具体如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//重点关注这个类
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {
//重点关注这个方法
boolean autoRegister() default true;
}
好吧,通过观察发现,这个是一个注解驱动类,并且默认就开启自动配置。你会恍然大悟,原来我在项目中,按照如下方式就可以开启服务注册与订阅(基于Spring Cloud Alibaba)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
//加上一个注解
@EnableDiscoveryClient
public class DistributedServerApplication {
public static void main(String[] args) {
SpringApplication.run(DistributedServerApplication.class, args);
}
}
如果是对技术有洁癖的开发人员 ,肯定还是会想,这个怎么做到的呢?于是就会打开EnableDiscoveryClientImportSelector类,部分代码演示如下。
@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class EnableDiscoveryClientImportSelector
extends SpringFactoryImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
...
//默认autoRegister=true
if (autoRegister) {
List importsList = new ArrayList<>(Arrays.asList(imports));
//默认使用Spring Boot的自动装配原理,初始化AutoServiceRegistrationConfiguration类,注意需要关注这个类
importsList.add( "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
imports = importsList.toArray(new String[0]);
}
...
}
}
好吧,看到这里也许你会觉得,这个不就是Spring Boot的自动装配的原理吗?很简单啊,但是你又要想想,它是怎么将Spring Cloud ALibaba与Spring Cloud 的服务注册与订阅的底层原理关联起来的呢?
如果是我,我会继续往下看AutoServiceRegistrationConfiguration类,如下所示。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
public class AutoServiceRegistrationConfiguration {
//这是一个什么类,我相信大家第一反应都是这么认为的,我擦。
//那么重点关注注解@EnableConfigurationProperties,它会让AutoServiceRegistrationProperties类,完成Spring IOC容器中的Bean的装配,也就是IOC容器中会有这么一个Bean对象(Bean的类型为AutoServiceRegistrationProperties类)
}
好吧,这个时候你才有点理解了,原来是利用了Spring Boot 的条件注解,控制Bean的装配。那么你又有没有想过,为什么要使用条件注解控制这个Bean的初始化,从因果关系的角度去想,肯定是有地方要靠这个Bean来做开关呢。
于是,我尝试着去查一下,还真被我猜中了,具体如下。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class,
NacosDiscoveryAutoConfiguration.class })
public class NacosServiceRegistryAutoConfiguration {
...
//好吧,我的亲爹,原来是为了控制NacosRegistration的初始化
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosRegistration nacosRegistration(
ObjectProvider> registrationCustomizers,
NacosDiscoveryProperties nacosDiscoveryProperties,
ApplicationContext context) {
return new NacosRegistration(registrationCustomizers.getIfAvailable(),
nacosDiscoveryProperties, context);
}
//原来也是为了控制NacosAutoServiceRegistration的初始化
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosAutoServiceRegistration nacosAutoServiceRegistration(
NacosServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
...
}
分析完之后,是不是很熟悉NacosServiceRegistryAutoConfiguration类,没错这个就是Spring Cloud Alibaba的项目spring-cloud-starter-alibaba-nacos-discovery中的一个普通的Java 类。
好吧,是不是通过我这样梳理之后,感觉原来如此,恍然大悟。
如果想了解更多关于Spring Cloud Alibaba的体系化的原理分析和项目实战,可以查阅本人出版的技术类书籍“Spring Cloud Alibaba微服务架构实战派(上下两册)”。
35岁程序员,还是要具备代码细节能力,应了行业内大佬说的话,要有清零的思维,把自己当作一个技术小白,重新认识自己。
欢迎关注公众号-35岁程序员那些事