springcloud alibaba 开启服务自动注册使用注解:
@EnableDiscoveryClient
结合到spring-cloud-starter-alibaba-nacos-discovery依赖,查看META-INF中spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
//NacosServiceRegistryAutoConfiguration为Nacos服务注册配置类
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\
com.alibaba.cloud.nacos.NacosServiceAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration看到NacosServiceRegistryAutoConfiguration,查看源码:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
//AutoConfigureAfter 顾名思义,需要的前置配置类
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class,
NacosDiscoveryAutoConfiguration.class })
public class NacosServiceRegistryAutoConfiguration {
@Bean
public NacosServiceRegistry nacosServiceRegistry(
NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosServiceRegistry(nacosDiscoveryProperties);
}
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosRegistration nacosRegistration(
ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,
NacosDiscoveryProperties nacosDiscoveryProperties,
ApplicationContext context) {
return new NacosRegistration(registrationCustomizers.getIfAvailable(),
nacosDiscoveryProperties, context);
}
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
public NacosAutoServiceRegistration nacosAutoServiceRegistration(
NacosServiceRegistry registry,
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
}备注:
NacosServiceRegistryAutoConfiguration中有一条注解:
@AutoConfigureAfter
包含三个类:
AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class,
NacosDiscoveryAutoConfiguration.class
注:其中AutoServiceRegistrationAutoConfiguration是通过@EnableDiscoveryClient注解注入到spring中,可以看出,如果要开启NacosServiceRegitryAutoConfiguration,必须先加载配置AutoSeviceRegistrationAutoConfiguration。所以,这就是为什么需要使用@EnableDiscoveryClient注解,来开启服务的自动注册。
在NacosServiceRegistryAutoConfiguration中配置了三个BEAN
1.NacosServiceRegistry
2.NacosRegistration
3.NacosAutoServiceRegistration
1.NacosServiceRegistry 可以理解为Nacos服务注册器,实现了ServiceRegistry,泛型为Registration(Registration可以理解为注册信息封装类)。包含registry、deRegistry方法,由此可知,该类是完成服务的注册、注销功能,这两个方式均为接口方法的实现
public class NacosServiceRegistry implements ServiceRegistry<Registration>
//注册
public void register(Registration registration)
//注销
public void deregister(Registration registration)2.NacosRegistration 该类为注册信息的封装类
NacosRegistration实现了Registration、ServiceInstance根据1中NacosServiceRegistry实现接口的泛型类型以及registrer/deregistrer方法的入参,可以大致了解到,需要将NacosRegistration信息封装后,传递到NacosServiceRegistry中,完成服务的注册、注销
NacosRegistration中init方法中使用@PostConstruct注解,主要是在类完成构建后,获取服务配置信息的收集
public class NacosRegistration implements Registration, ServiceInstance
@PostConstruct
public void init()3.NacosAutoServiceRegistration Nacos自动服务注册 主要是完成服务的自动注册
public class NacosAutoServiceRegistration
extends AbstractAutoServiceRegistration<Registration>
public abstract class AbstractAutoServiceRegistration<R extends Registration>
implements AutoServiceRegistration, ApplicationContextAware,
ApplicationListener<WebServerInitializedEvent>NacosAutoServiceRegistration 继承 AbstractAutoServiceRegistration , AbstractAutoServiceRegistration 实现了 ApplicationListener<WebServerInitializedEvent> 的onApplicationEvent方法
1.WebServerInitializedEvent事件后,执行onApplicationEvent方法
public void onApplicationEvent(WebServerInitializedEvent event) {
bind(event);
}2.进入bind方法
public void bind(WebServerInitializedEvent event) {
ApplicationContext context = event.getApplicationContext();
if (context instanceof ConfigurableWebServerApplicationContext) {
if ("management".equals(((ConfigurableWebServerApplicationContext) context)
.getServerNamespace())) {
return;
}
}
this.port.compareAndSet(0, event.getWebServer().getPort());
this.start();
}3.进入start方法
public void start() {
if (!isEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Discovery Lifecycle disabled. Not starting");
}
return;
}
// only initialize if nonSecurePort is greater than 0 and it isn't already running
// because of containerPortInitializer below
if (!this.running.get()) {
this.context.publishEvent(
new InstancePreRegisteredEvent(this, getRegistration()));
register();
if (shouldRegisterManagement()) {
registerManagement();
}
this.context.publishEvent(
new InstanceRegisteredEvent<>(this, getConfiguration()));
this.running.compareAndSet(false, true);
}
}4.进入register方法
protected void register() {
this.serviceRegistry.register(getRegistration());
}由于NacosAutoServiceRegistration配置了NacosRegistry,此处的调用直接到NacosServiceRegistry的register方法
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
NamingService namingService = namingService();
String serviceId = registration.getServiceId();
String group = nacosDiscoveryProperties.getGroup();
Instance instance = getNacosInstanceFromRegistration(registration);
try {
namingService.registerInstance(serviceId, group, instance);
log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
instance.getIp(), instance.getPort());
}
catch (Exception e) {
log.error("nacos registry, {} register failed...{},", serviceId,
registration.toString(), e);
// rethrow a RuntimeException if the registration is failed.
// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
rethrowRuntimeException(e);
}
}此处需要注意两行代码:
1.NamingService namingService = namingService();
获取namingService
2.namingService.registerInstance(serviceId, group, instance);
使用namingservice注册实例
获取namingService
1.通过nacosServiceManager获取namingService
private NamingService namingService() {
return nacosServiceManager
.getNamingService(nacosDiscoveryProperties.getNacosProperties());
}
调用栈:
NacosServiceManager
getNamingService
->buildNamingService
->createNewNamingService
->createNamingService
->NamingFactory.createNamingService(properties);从NamingFactory正式从nacos-discovery依赖到nacos-api进入初始化NamingService的流程
后续调用NamingsService完成服务注册。
下一章:解读NamingService初始化