spring cloud nacos获取Nacos服务端的配置信息过程解析

bootstrap的上下文创建:

SpringApplication.java:run
----->prepareEnvironment
----->EventPublishingRunListener发送ApplicationEnvironmentPreparedEvent事件
----->BootstrapApplicationListener接收事件,调用onApplicationEvent方法(事件机制)
----->bootstrapServiceContext创建bootstrap的context
context = bootstrapServiceContext(environment, event.getSpringApplication(),
		configName);

在run方法里面,执行prepareEnvironment,通过事件机制(这里是同步机制),bootstrapServiceContext方法,创建bootstrap的上下文。bootstrap的上下文是AnnotationConfigApplicationContext类型的。通过这个,去解析bootstrap的配置文件。并且设置为App上下文的parent。

// Make the bootstrap context a parent of the app context
addAncestorInitializer(application, context);

为了避免执行上下文run方法的时候,再次创建新的上下文。

if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
	return;
}

bootstrap的上下文在启动的过程中,去加载nacos服务端的配置信息。
具体流程是这样的:
获取配置过程:

------->1、SpringApplication.java:run方法(spring-boot.jar)
------->2、SpringApplication.java:prepareContext方法(spring-boot.jar)
------->3、SpringApplication.java:applyInitializers方法(spring-boot.jar)
------->4、PropertySourceBootstrapConfiguration.java:initialize方法(spring-cloud-context.jar)
------->5、NacosPropertySourceLocator.java:locateCollection方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->6、NacosPropertySourceLocator.java:locate方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->7、NacosPropertySourceLocator.java:loadApplicationConfiguration方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->8、NacosPropertySourceLocator.java:loadNacosDataIfPresent方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->9、NacosPropertySourceLocator.java:loadNacosPropertySource方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->10、NacosPropertySourceBuilder.java:build方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->11、NacosPropertySourceBuilder.java:loadNacosData方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->12、NacosConfigService.java:getConfig方法(nacos-client.jar)
------->13、NacosConfigService.java:getConfigInner方法(nacos-client.jar)
------->14、ClientWorker.java:getServerConfig方法(nacos-client.jar)

第4步说明:
PropertySourceBootstrapConfiguration实现了ApplicationContextInitializer接口。使用ApplicationContextInitializer机制实现了扩展。PropertySourceBootstrapConfiguration是通过解析spring-cloud-context.jar包里面的spring.factories文件获得的。

# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\
org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.cloud.util.random.CachedRandomPropertySourceAutoConfiguration

getSpringFactoriesInstances读取并解析jar包下的spring.factories配置文件:

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
	setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	this.mainApplicationClass = deduceMainApplicationClass();
}

注册listener的过程:

------->1、SpringApplication.java:run方法(spring-boot.jar)
------->2、SpringApplicationRunListeners.java:running方法(spring-boot.jar)
------->3、EventPublishingRunListener.java:running方法(spring-boot.jar)
------->4、AnnotationConfigServletWebServerApplicationContext.java:publishEvent方法(spring-context.jar)
------->5、AnnotationConfigServletWebServerApplicationContext.java:publishEvent方法(spring-context.jar)
------->6、SimpleApplicationEventMulticaster.java:multicastEvent方法(spring-context.jar) listener:NacosContextRefresher
------->7、SimpleApplicationEventMulticaster.java:invokeListener方法(spring-context.jar)
------->8、SimpleApplicationEventMulticaster.java:doInvokeListener方法(spring-context.jar)
------->9、NacosContextRefresher.java:onApplicationEvent方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->10、NacosContextRefresher.java:registerNacosListenersForApplications方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->11、NacosContextRefresher.java:registerNacosListener方法(spring-cloud-starter-alibaba-nacos-config.jar)
------->12、NacosConfigService.java:addListener方法(nacos-client.jar)
------->13、ClientWorker.java:addTenantListeners方法(nacos-client.jar)

入口,run方法:

try {
	listeners.running(context);
}
catch (Throwable ex) {
	handleRunFailure(context, ex, exceptionReporters, null);
	throw new IllegalStateException(ex);
}
return context;

通过事件机制完成listener的注册,发送的事件是ApplicationReadyEvent。接收器是NacosContextRefresher,实现了ApplicationListener接口。在回调方法onApplicationEvent中,实现对listener的注册。

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
	// many Spring context
	if (this.ready.compareAndSet(false, true)) {
		this.registerNacosListenersForApplications();
	}
}

参考:
https://zhuanlan.zhihu.com/p/63007278
https://www.cnblogs.com/duanxz/p/11239291.html

说明:
spring-cloud-context版本是2.2.3.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值