美文网首页程序员
Nacos Config Spring Cloud

Nacos Config Spring Cloud

作者: 鱼蛮子9527 | 来源:发表于2022-05-23 09:20 被阅读0次

这里分析下Nacos Config在Spring Cloud下的使用。整体调用链路如下表所示。

NacosConfigBootstrapConfiguration
nacosConfigProperties()
nacosConfigManager()
nacosPropertySourceLocator()
NacosPropertySourceLocator#locate()
loadSharedConfiguration()
loadExtConfiguration()
loadApplicationConfiguration()
NacosConfigAutoConfiguration
nacosConfigProperties()
nacosRefreshHistory()
nacosConfigManager()
nacosContextRefresher()
NacosContextRefresher#onApplicationEvent()
registerNacosListenersForApplications()
registerNacosListener()

NacosConfigBootstrapConfiguration

nacosConfigProperties()

加载了spring.cloud.nacos相关配置,生成NacosConfigProperties。

nacosConfigManager()

初始化了NacosConfigManager,主要是根据NacosConfigProperties初始化了ConfigService,这个也是Nacos Client 对外保留的核心对象,用于获取配置,添加监听等。

nacosPropertySourceLocator()

用于初始化了NacosPropertySourceLocator对象,实现了PropertySourceLocator接口,用于加载额外的配置信息。

NacosPropertySourceLocator#locate()

public PropertySource<?> locate(Environment env) {
    ConfigService configService = this.nacosConfigProperties.configServiceInstance();
    if (null == configService) {
        log.warn("no instance of config service found, can't load config from nacos");
        return null;
    } else {
        long timeout = (long)this.nacosConfigProperties.getTimeout();
        this.nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout);
        String name = this.nacosConfigProperties.getName();
        String dataIdPrefix = this.nacosConfigProperties.getPrefix();
        if (StringUtils.isEmpty(dataIdPrefix)) {
            dataIdPrefix = name;
        }

        if (StringUtils.isEmpty(dataIdPrefix)) {
            dataIdPrefix = env.getProperty("spring.application.name");
        }

        CompositePropertySource composite = new CompositePropertySource("NACOS");
        this.loadSharedConfiguration(composite);
        this.loadExtConfiguration(composite);
        this.loadApplicationConfiguration(composite, dataIdPrefix, this.nacosConfigProperties, env);
        return composite;
    }
}

loadSharedConfiguration()

加载分布式的配置,形如spring.cloud.nacos.config.shared-configs[0]=xxx 的配置。

loadExtConfiguration()

加载扩展配置,如spring.cloud.nacos.config.extension-configs[0]=xxx ,其实我没搞明白这俩有啥区别。

loadApplicationConfiguration()

加载应用主配置信息,这里会加载默认的两个配置,dataIdPrefix+group与dataIdPrefix.fileExtension+group,如果不想加载可以通过配置spring.cloud.nacos.config.group=来避免加载,只加载上面的shared-configs与extension-configs的配置。

NacosConfigAutoConfiguration

nacosConfigProperties()

这里会判断是否有父Context并且包含了NacosConfigProperties,如果有从父Context中直接获取。

nacosRefreshHistory()

初始化了NacosRefreshHistory,用于存储Nacos数据更新历史,最大存储20条。

nacosConfigManager()

初始化了NacosConfigManager,与上面的一致。

nacosContextRefresher()

初始化了NacosContextRefresher,这个是比较核心的类,这个类实现了ApplicationListener,监听ApplicationReadyEvent事件,在Application完成的时候,执行Nacos变化监听。

NacosContextRefresher#onApplicationEvent()

registerNacosListenersForApplications() --> registerNacosListener() --> 这里会新建一个Listener,并通过configService#addListener()方法添加到Nacos的变化监听中。当收到变化的时候,首先添加了刷新纪录nacosRefreshHistory#addRefreshRecord(),其次发布了RefreshEvent事件。

在发布了RefreshEvent事件之后,就可以使用Spring Cloud自带的RefreshScope机制来实现属性的刷新了。在Spring Cloud 监听到变化,会执行ContextRefresher#refresh()。首先会重新加载引导信息,也就会重新调用NacosPropertySourceLocator#locate(),从而从Nacos中读取最新的配置。其次会清空缓存对象,重新以最新的Enviroment生成对象,来达到属性更新的目的。

整体来说Nacos Config在Spring Cloud的实现比较简单。核心使用了Spring Cloud的RefreshScope机制来实现对象属性的动态刷新。

相关文章

网友评论

    本文标题:Nacos Config Spring Cloud

    本文链接:https://www.haomeiwen.com/subject/mchjprtx.html