Nacos自动装配原理
在Spring Cloud稍早一些的版本中,我们需要在启动类上添加@EnableDiscoveryClient注解开启服务治理功能,而在新版本的Spring Cloud中,这个注解不再是一个必须的步骤,我们只需要通过配置项就可以开启Nacos的功能。那么Nacos是怎么在启动阶段自动加载配置项并开启相关功能的呢?这就要从Spring Framework的自动装配流程(Auto Configuration)说起了。
我们将Nacos依赖项添加到项目中,同时也引入了Nacos自带的自动装配器,比如下面这几个被引入的自动装配器就掌管了Nacos核心功能的初始化任务。
我们以NacosDiscoveryAutoConfiguration类为例,了解一下它是怎么样工作的,先来看一下它的源码
@Configuration(proxyBeanMethods = false)
// 当spring.cloud.discovery.enabled=true时才生效
@ConditionalOnDiscoveryEnabled
// 当spring.cloud.nacos.discovery.enabled=true时生效
@ConditionalOnNacosDiscoveryEnabled
public class NacosDiscoveryAutoConfiguration {
// 读取Nacos所有配置项并封装到NacosDiscoveryProperties中
@Bean
@ConditionalOnMissingBean
public NacosDiscoveryProperties nacosProperties() {
return new NacosDiscoveryProperties();
}
// 声明服务发现的功能类NacosServiceDiscovery
@Bean
@ConditionalOnMissingBean
public NacosServiceDiscovery nacosServiceDiscovery(
NacosDiscoveryProperties discoveryProperties,
NacosServiceManager nacosServiceManager) {
return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager);
}
}
NacosDiscoveryAutoConfiguration自动装配器有两个开启条件,分别是spring.cloud.discovery.enabled=true和spring.cloud.nacos.discovery.enabled=true。
注意:很多配置文件
当我们引入Nacos的依赖项后,默认情况下这两个开关参数的值就已经是True了。也就是说,除非你主动关闭Spring Cloud和Nacos的服务发现开关,否则这个自动装配器就会自动执行加载。
接下来,我们来了解一下NacosDiscoveryAutoConfiguration中声明的两个方法,也就是nacosProperties方法和nacosServiceDiscovery方法都有什么功能。
在上面的源码中,我们看到,nacosProperties方法返回了一个NacosDiscoveryProperties类,这个类是专门用来读取和封装Nacos配置项的类,它的源码如下:
// 定义了配置项读取的路径
@ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {
// 省略类属性
// 这里定义的类属性和接下来我们要介绍的配置项是一一对应的
}
NacosDiscoveryProperties类通过ConfigurationProperties注解从spring.cloud.nacos.discovery路径下获取配置项,Spring框架会自动将这些配置项解析到NacosDiscoveryProperties类定义的类属性中。这样一来Nacos就完成了配置项的加载,在其它业务流程中,只需要注入NacosDiscoveryProperties类就可以读取Nacos的配置参数。
NacosDiscoveryAutoConfiguration中的另一个方法nacosServiceDiscovery声明了一个服务发现的功能类NacosServiceDiscovery,它的核心方法的源码如下:
public class NacosServiceDiscovery {
// 封装了Nacos配置项的类
private NacosDiscoveryProperties discoveryProperties;
// 另一个自动装配器声明的核心服务治理类
private NacosServiceManager nacosServiceManager;
// 根据服务名称获取所有已注册服务
public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
String group = discoveryProperties.getGroup();
List<Instance> instances = namingService().selectInstances(serviceId, group,
true);
return hostToServiceInstanceList(instances, serviceId);
}
// 返回所有服务的服务名称
public List<String> getServices() throws NacosException {
String group = discoveryProperties.getGroup();
ListView<String> services = namingService().getServicesOfServer(1,
Integer.MAX_VALUE, group);
return services.getData();
}
// 省略部分代码...
}