您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring Cloud Alibaba Nacos Config加載如何配置”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
SpringBoot啟動時,會執行這個方法:SpringApplication#run,這個方法中會調prepareContext來準備上下文,這個方法中調用了applyInitializers方法來執行實現了ApplicationContextInitializer接口的類的initialize方法。其中包括PropertySourceBootstrapConfiguration#initialize 來加載外部的配置。
@Autowired(required = false) private List<PropertySourceLocator> propertySourceLocators = new ArrayList<>(); public void initialize(ConfigurableApplicationContext applicationContext) { ... for (PropertySourceLocator locator : this.propertySourceLocators) { //載入PropertySource Collection<PropertySource<?>> source = locator.locateCollection(environment); ... } ... } //org.springframework.cloud.bootstrap.config.PropertySourceLocator#locateCollection default Collection<PropertySource<?>> locateCollection(Environment environment) { return locateCollection(this, environment); } //org.springframework.cloud.bootstrap.config.PropertySourceLocator#locateCollection static Collection<PropertySource<?>> locateCollection(PropertySourceLocator locator, Environment environment) { //執行locate方法,將PropertySource加載進來 PropertySource<?> propertySource = locator.locate(environment); ... }
這個類中會注入實現了PropertySourceLocator接口的類,在nacos中是NacosPropertySourceLocator。
在initialize方法中會執行NacosPropertySourceLocator的locate方法,將NacosPropertySource加載進來。
NacosPropertySourceLocator在配置類NacosConfigBootstrapConfiguration中注冊。
@Configuration(proxyBeanMethods = false) @ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true) public class NacosConfigBootstrapConfiguration { @Bean @ConditionalOnMissingBean public NacosConfigProperties nacosConfigProperties() { return new NacosConfigProperties(); } @Bean @ConditionalOnMissingBean public NacosConfigManager nacosConfigManager( NacosConfigProperties nacosConfigProperties) { return new NacosConfigManager(nacosConfigProperties); } @Bean public NacosPropertySourceLocator nacosPropertySourceLocator( NacosConfigManager nacosConfigManager) { return new NacosPropertySourceLocator(nacosConfigManager); } }
在這里會依次注冊NacosConfigProperties,NacosConfigManager,NacosPropertySourceLocator。
//com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#locate public PropertySource<?> locate(Environment env) { nacosConfigProperties.setEnvironment(env); //獲取ConfigService ConfigService configService = nacosConfigManager.getConfigService(); if (null == configService) { log.warn("no instance of config service found, can't load config from nacos"); return null; } long timeout = nacosConfigProperties.getTimeout(); //構建nacosPropertySourceBuilder nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout); String name = nacosConfigProperties.getName(); //獲取dataIdPrefix,一次從prefix,name,spring.application.name中獲取 String dataIdPrefix = nacosConfigProperties.getPrefix(); if (StringUtils.isEmpty(dataIdPrefix)) { dataIdPrefix = name; } if (StringUtils.isEmpty(dataIdPrefix)) { dataIdPrefix = env.getProperty("spring.application.name"); } //構建CompositePropertySource:NACOS CompositePropertySource composite = new CompositePropertySource( NACOS_PROPERTY_SOURCE_NAME); //加載share 配置 loadSharedConfiguration(composite); //加載extention 配置 loadExtConfiguration(composite); //加載application配置 loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env); return composite; }
private void loadSharedConfiguration( CompositePropertySource compositePropertySource) { //獲取share節點的配置信息 List<NacosConfigProperties.Config> sharedConfigs = nacosConfigProperties .getSharedConfigs(); //如果不為空,加載 if (!CollectionUtils.isEmpty(sharedConfigs)) { checkConfiguration(sharedConfigs, "shared-configs"); loadNacosConfiguration(compositePropertySource, sharedConfigs); } }
加載配置,公用方法
//com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#loadNacosConfiguration private void loadNacosConfiguration(final CompositePropertySource composite, List<NacosConfigProperties.Config> configs) { for (NacosConfigProperties.Config config : configs) { loadNacosDataIfPresent(composite, config.getDataId(), config.getGroup(), NacosDataParserHandler.getInstance() .getFileExtension(config.getDataId()), config.isRefresh()); } }
//com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#loadNacosDataIfPresent private void loadNacosDataIfPresent(final CompositePropertySource composite, final String dataId, final String group, String fileExtension, boolean isRefreshable) { if (null == dataId || dataId.trim().length() < 1) { return; } if (null == group || group.trim().length() < 1) { return; } //加載NacosPropertySource,后面也會用這個方法 NacosPropertySource propertySource = this.loadNacosPropertySource(dataId, group, fileExtension, isRefreshable); //將NacosPropertySource放入第一個 this.addFirstPropertySource(composite, propertySource, false); }
加載NacosPropertySource
//com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#loadNacosPropertySource private NacosPropertySource loadNacosPropertySource(final String dataId, final String group, String fileExtension, boolean isRefreshable) { //標注@RefreshScope的類的數量不為0,且不允許自動刷新,從緩存加載nacos的配置 if (NacosContextRefresher.getRefreshCount() != 0) { if (!isRefreshable) { return NacosPropertySourceRepository.getNacosPropertySource(dataId, group); } } return nacosPropertySourceBuilder.build(dataId, group, fileExtension, isRefreshable); }
從緩存中加載
//NacosPropertySourceRepository private final static ConcurrentHashMap<String, NacosPropertySource> NACOS_PROPERTY_SOURCE_REPOSITORY = new ConcurrentHashMap<>(); public static NacosPropertySource getNacosPropertySource(String dataId, String group) { return NACOS_PROPERTY_SOURCE_REPOSITORY.get(getMapKey(dataId, group)); } public static String getMapKey(String dataId, String group) { return String.join(NacosConfigProperties.COMMAS, String.valueOf(dataId), String.valueOf(group)); }
NacosPropertySourceRepository中緩存了NacosPropertySource
獲取配置并加入緩存
//com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder#build NacosPropertySource build(String dataId, String group, String fileExtension, boolean isRefreshable) { //獲取配置 List<PropertySource<?>> propertySources = loadNacosData(dataId, group, fileExtension); //包裝成NacosPropertySource NacosPropertySource nacosPropertySource = new NacosPropertySource(propertySources, group, dataId, new Date(), isRefreshable); //加入緩存 NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource); return nacosPropertySource; }
//com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder#loadNacosData private List<PropertySource<?>> loadNacosData(String dataId, String group, String fileExtension) { String data = null; try { //獲取配置 data = configService.getConfig(dataId, group, timeout); if (StringUtils.isEmpty(data)) { log.warn( "Ignore the empty nacos configuration and get it based on dataId[{}] & group[{}]", dataId, group); return Collections.emptyList(); } if (log.isDebugEnabled()) { log.debug(String.format( "Loading nacos data, dataId: '%s', group: '%s', data: %s", dataId, group, data)); } return NacosDataParserHandler.getInstance().parseNacosData(dataId, data, fileExtension); } catch (NacosException e) { log.error("get data from Nacos error,dataId:{} ", dataId, e); } catch (Exception e) { log.error("parse data from Nacos error,dataId:{},data:{}", dataId, data, e); } return Collections.emptyList(); }
//com.alibaba.nacos.client.config.NacosConfigService#getConfig public String getConfig(String dataId, String group, long timeoutMs) throws NacosException { return getConfigInner(namespace, dataId, group, timeoutMs); }
//com.alibaba.nacos.client.config.NacosConfigService#getConfigInner private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException { group = blank2defaultGroup(group); ParamUtils.checkKeyParam(dataId, group); //聲明響應 ConfigResponse cr = new ConfigResponse(); //設置dataId,tenant,group cr.setDataId(dataId); cr.setTenant(tenant); cr.setGroup(group); // use local config first //先從本地緩存中加載 String content = LocalConfigInfoProcessor.getFailover(worker.getAgentName(), dataId, group, tenant); if (content != null) { LOGGER.warn("[{}] [get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", worker.getAgentName(), dataId, group, tenant, ContentUtils.truncateContent(content)); cr.setContent(content); String encryptedDataKey = LocalEncryptedDataKeyProcessor .getEncryptDataKeyFailover(agent.getName(), dataId, group, tenant); cr.setEncryptedDataKey(encryptedDataKey); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; } try { //從服務器獲取配置 ConfigResponse response = worker.getServerConfig(dataId, group, tenant, timeoutMs, false); cr.setContent(response.getContent()); cr.setEncryptedDataKey(response.getEncryptedDataKey()); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; } catch (NacosException ioe) { if (NacosException.NO_RIGHT == ioe.getErrCode()) { throw ioe; } LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}", worker.getAgentName(), dataId, group, tenant, ioe.toString()); } LOGGER.warn("[{}] [get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", worker.getAgentName(), dataId, group, tenant, ContentUtils.truncateContent(content)); content = LocalConfigInfoProcessor.getSnapshot(worker.getAgentName(), dataId, group, tenant); cr.setContent(content); String encryptedDataKey = LocalEncryptedDataKeyProcessor .getEncryptDataKeyFailover(agent.getName(), dataId, group, tenant); cr.setEncryptedDataKey(encryptedDataKey); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; }
將NacosPropertySource加入composite的第一個
//com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#addFirstPropertySource private void addFirstPropertySource(final CompositePropertySource composite, NacosPropertySource nacosPropertySource, boolean ignoreEmpty) { if (null == nacosPropertySource || null == composite) { return; } if (ignoreEmpty && nacosPropertySource.getSource().isEmpty()) { return; } composite.addFirstPropertySource(nacosPropertySource); }
private void loadExtConfiguration(CompositePropertySource compositePropertySource) { //獲取extention節點的配置信息 List<NacosConfigProperties.Config> extConfigs = nacosConfigProperties .getExtensionConfigs(); //如果不為空,加載 if (!CollectionUtils.isEmpty(extConfigs)) { checkConfiguration(extConfigs, "extension-configs"); loadNacosConfiguration(compositePropertySource, extConfigs); } }
private void loadApplicationConfiguration( CompositePropertySource compositePropertySource, String dataIdPrefix, NacosConfigProperties properties, Environment environment) { //獲取文件擴展名 String fileExtension = properties.getFileExtension(); //獲取group String nacosGroup = properties.getGroup(); // load directly once by default //加載nacos的配置 loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup, fileExtension, true); // load with suffix, which have a higher priority than the default //加載帶后綴的配置,優先級高于上一個 loadNacosDataIfPresent(compositePropertySource, dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true); // Loaded with profile, which have a higher priority than the suffix for (String profile : environment.getActiveProfiles()) { String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension; //加載帶profile,文件格式后綴的配置,優先級高于上一個 loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup, fileExtension, true); } }
這里會加載至少三個nacos上面的配置文件,按優先級依次為application,application.yaml,application-dev.yaml。
“Spring Cloud Alibaba Nacos Config加載如何配置”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。