Springboot集成Nacos后配置属性加载顺序问题

文章目录

  • 结论
  • 分析
    • 1. 加载application.properties
    • 2. 加载nacos属性
      • 1. 获取nacos属性
      • 2. 添加NacosPropertySource
    • 3. spring的所有环境属性列表
      • 1. propertySourceList示例图
    • 4. 获取属性
      • 1. applicationContext.getEnvironment().getProperty()
      • 2. @Value注入属性


结论

在项目中同时使用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

private void addNacosPropertySource(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);
   }
   else if (isRelative) { // If relative
      if (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示例图

Springboot集成Nacos后配置属性加载顺序问题_第1张图片

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 instanceof String) {
      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循环取,取到即跳出循环

@Nullable
protected <T> T getProperty(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 instanceof String) {
               value = resolveNestedPlaceholders((String) value);
            }
            logKeyFound(key, propertySource, value);
            return convertValueIfNecessary(value, targetValueType);
         }
      }
   }
   if (logger.isTraceEnabled()) {
      logger.trace("Could not find key '" + key + "' in any property source");
   }
   return null;
}

你可能感兴趣的:(Java,spring,boot,java,spring)