文章24 | 阅读 12823 | 点赞0
Nacos除了Bootstrap的自动配置类,同时也配置了SpringBoot的自动配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration
NacosConfigEndpointAutoConfiguration这个是端点的,就不分析了。我们看NacosConfigAutoConfiguration:
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
public class NacosConfigAutoConfiguration {
@Bean
public NacosConfigProperties nacosConfigProperties(ApplicationContext context) {
if (context.getParent() != null
&& BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
context.getParent(), NacosConfigProperties.class).length > 0) {
return BeanFactoryUtils.beanOfTypeIncludingAncestors(context.getParent(),
NacosConfigProperties.class);
}
return new NacosConfigProperties();
}
@Bean
public NacosRefreshProperties nacosRefreshProperties() {
return new NacosRefreshProperties();
}
@Bean
public NacosRefreshHistory nacosRefreshHistory() {
return new NacosRefreshHistory();
}
@Bean
public NacosConfigManager nacosConfigManager(
NacosConfigProperties nacosConfigProperties) {
return new NacosConfigManager(nacosConfigProperties);
}
@Bean
public NacosContextRefresher nacosContextRefresher(
NacosConfigManager nacosConfigManager,
NacosRefreshHistory nacosRefreshHistory) {
// Consider that it is not necessary to be compatible with the previous
// configuration
// and use the new configuration if necessary.
return new NacosContextRefresher(nacosConfigManager, nacosRefreshHistory);
}
}
首先搞清楚一个,这个配置类是定义在主应用上下文中的,也就是说这里定义的这些bean和NacosConfigBootstrapConfiguration中定义的并不是在同一个容器中。
NacosConfigProperties是从Bootstrap上下文容器中实例并返回。等于是两个上下文的容器中共存一份。
这个已经废弃了。
这个类就是用来对获取的配置数据内容用md5
加密作为历史记录,然后存在在一个集合里。
public NacosRefreshHistory() {
try {
md = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e) {
log.error("failed to initialize MessageDigest : ", e);
}
}
添加记录:
public void addRefreshRecord(String dataId, String group, String data) {
records.addFirst(new Record(DATE_FORMAT.get().format(new Date()), dataId, group,
md5(data), null));
if (records.size() > MAX_SIZE) {
records.removeLast();
}
}
md5方法:
private String md5(String data) {
if (StringUtils.isEmpty(data)) {
return null;
}
if (null == md) {
try {
md = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException ignored) {
return "unable to get md5";
}
}
return new BigInteger(1, md.digest(data.getBytes(StandardCharsets.UTF_8)))
.toString(16);
}
Record类定义:
static class Record {
private final String timestamp;
private final String dataId;
private final String group;
private final String md5;
Record(String timestamp, String dataId, String group, String md5,
Map<String, Object> last) {
this.timestamp = timestamp;
this.dataId = dataId;
this.group = group;
this.md5 = md5;
}
....
}
添加监听用的。首先它本身就是一个ApplicationListener监听器,监听ApplicationReadyEvent事件:
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// many Spring context
if (this.ready.compareAndSet(false, true)) {
this.registerNacosListenersForApplications();
}
}
事件触发时,注册Nacos的监听器:
/**
* register Nacos Listeners.
*/
private void registerNacosListenersForApplications() {
if (isRefreshEnabled()) {
for (NacosPropertySource propertySource : NacosPropertySourceRepository
.getAll()) {
if (!propertySource.isRefreshable()) {
continue;
}
String dataId = propertySource.getDataId();
registerNacosListener(propertySource.getGroup(), dataId);
}
}
}
private void registerNacosListener(final String groupKey, final String dataKey) {
String key = NacosPropertySourceRepository.getMapKey(dataKey, groupKey);
Listener listener = listenerMap.computeIfAbsent(key,
lst -> new AbstractSharedListener() {
@Override
public void innerReceive(String dataId, String group,
String configInfo) {
refreshCountIncrement();
nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo);
// todo feature: support single refresh for listening
applicationContext.publishEvent(
new RefreshEvent(this, null, "Refresh Nacos config"));
if (log.isDebugEnabled()) {
log.debug(String.format(
"Refresh Nacos config group=%s,dataId=%s,configInfo=%s",
group, dataId, configInfo));
}
}
});
try {
configService.addListener(dataKey, groupKey, listener);
}
catch (NacosException e) {
log.warn(String.format(
"register fail for nacos listener ,dataId=[%s],group=[%s]", dataKey,
groupKey), e);
}
}
configService添加上面定义的监听器。 这个前面分析过,当长轮询检测到配置变更时会触发监听器的receiveConfigInfo方法,这个在AbstractSharedListener中定义:
@Override
public final void receiveConfigInfo(String configInfo) {
innerReceive(dataId, group, configInfo);
}
就是调用了模板方法innerReceive
innerReceive方法的实现内容:
整理一下NacosConfigBootstrapConfiguration和NacosConfigAutoConfiguration这两个配置类定义的bean:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_19414183/article/details/112257297
内容来源于网络,如有侵权,请联系作者删除!