文章目录
结论
在项目中同时使用nacos加载配置属性和application.properties配置文件,默认情况下,先加载application.properties后加载nacos的配置文件,读取属性是先读取application.propeties,没找到才会读取nacos的配置。
分析
1. 加载application.properties
org.springframework.boot.context.config.ConfigFileApplicationListener
2. 加载nacos属性
1. 获取nacos属性
com.alibaba.nacos.spring.core.env.AbstractNacosPropertySourceBuilder#doBuild
String nacosConfig = nacosConfigLoader.load(dataId, groupId, nacosProperties);
2. 添加NacosPropertySource
com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor#addNacosPropertySource
privatevoidaddNacosPropertySource(NacosPropertySource nacosPropertySource){MutablePropertySources propertySources = environment.getPropertySources();boolean first = nacosPropertySource.isFirst();String before = nacosPropertySource.getBefore();String after = nacosPropertySource.getAfter();boolean hasBefore =!nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, before);boolean hasAfter =!nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, after);boolean isRelative = hasBefore || hasAfter;if(first){// If First
propertySources.addFirst(nacosPropertySource);}elseif(isRelative){// If relativeif(hasBefore){
propertySources.addBefore(before, nacosPropertySource);}if(hasAfter){
propertySources.addAfter(after, nacosPropertySource);}}else{
propertySources.addLast(nacosPropertySource);// default add last}}
3. spring的所有环境属性列表
org.springframework.core.env.MutablePropertySources#propertySourceList
1. propertySourceList示例图
4. 获取属性
1. applicationContext.getEnvironment().getProperty()
2. @Value注入属性
org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
Class<?> type = descriptor.getDependencyType();Object value =getAutowireCandidateResolver().getSuggestedValue(descriptor);if(value !=null){if(value instanceofString){String strVal =resolveEmbeddedValue((String) value);BeanDefinition bd =(beanName !=null&&containsBean(beanName)?getMergedBeanDefinition(beanName):null);
value =evaluateBeanDefinitionString(strVal, bd);}TypeConverter converter =(typeConverter !=null? typeConverter :getTypeConverter());try{return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());}catch(UnsupportedOperationException ex){// A custom TypeConverter which does not support TypeDescriptor resolution...return(descriptor.getField()!=null?
converter.convertIfNecessary(value, type, descriptor.getField()):
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}}
两种方式最后是相同的获取属性的方法,org.springframework.core.env.PropertyResolver#getProperty(java.lang.String),按照PropertySourceList循环取,取到即跳出循环
@Nullableprotected<T>TgetProperty(String key,Class<T> targetValueType,boolean resolveNestedPlaceholders){if(this.propertySources !=null){for(PropertySource<?> propertySource :this.propertySources){if(logger.isTraceEnabled()){
logger.trace("Searching for key '"+ key +"' in PropertySource '"+
propertySource.getName()+"'");}Object value = propertySource.getProperty(key);if(value !=null){if(resolveNestedPlaceholders && value instanceofString){
value =resolveNestedPlaceholders((String) value);}logKeyFound(key, propertySource, value);returnconvertValueIfNecessary(value, targetValueType);}}}if(logger.isTraceEnabled()){
logger.trace("Could not find key '"+ key +"' in any property source");}returnnull;}
版权归原作者 fan_7788 所有, 如有侵权,请联系我们删除。