@ConfigurationProperties-数据绑定源码

1,621 阅读13分钟

不要问我阅读spring源码有什么用,问就是没有用,只是让我自己使用spring的过程中自信点!

相关文章

spring-相关文章

过程

1. @ConfigurationProperties 绑定数据是通过ben的后置处理器实现的
2. bean后置处理器是 ConfigurationPropertiesBindingPostProcessor
3. 流程为 ioc容器初始化 -> 创建目标bean -> 执行initializeBean -> 执行后置处理器 -> 对字段赋值
//这块代码段 是 ioc 容器初始化的 一部分  不清楚的可以看下以前的文章
//populateBean()  处理以来注入
//initializeBean()  后置处理器的一些处理  还有一些初始化的处理 
//例如 加入bean 实现了 InitializingBean 接口 执行其 afterPropertiesSet() 方法 之类... 
Object exposedObject = bean;
try {
	//这个依赖注入的不看了 以后会单独讲
    populateBean(beanName, mbd, instanceWrapper);
    //本文的重点
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
      if (System.getSecurityManager() != null) {
          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
              invokeAwareMethods(beanName, bean);
              return null;
          }, getAccessControlContext());
      }
      else {
      		//假如bean 实现了 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口 执行他们的实现方法
            //其实这个地方就可以当做一个bean的初始化的处理 
          invokeAwareMethods(beanName, bean);
      }

      Object wrappedBean = bean;
      if (mbd == null || !mbd.isSynthetic()) {
      		//主线
      		//执行后置处理器 Before
            // 数据绑定是 执行的 postProcessBeforeInitialization            
          wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
      }

      try {
      		//假如实现了InitializingBean 执行afterPropertiesSet()方法
          invokeInitMethods(beanName, wrappedBean, mbd);
      }
      catch (Throwable ex) {
          throw new BeanCreationException(
                  (mbd != null ? mbd.getResourceDescription() : null),
                  beanName, "Invocation of init method failed", ex);
      }
      if (mbd == null || !mbd.isSynthetic()) {
      	//执行后置处理器 After
          wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
      }

      return wrappedBean;
  }

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    //循坏  执行后置处理器
    //我们 关注  ConfigurationPropertiesBindingPostProcessor
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

ConfigurationPropertiesBindingPostProcessor

//当前代码位置  ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization()
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	//先看下ConfigurationPropertiesBean.get() 方法
    bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
    return bean;
}

//
public static ConfigurationPropertiesBean get(ApplicationContext applicationContext, Object bean, String beanName) {	
	  //查询工厂方法,就是看看是不是@bean 创建的 
      Method factoryMethod = findFactoryMethod(applicationContext, beanName);
      //创建ConfigurationPropertiesBean 
      //// 主要看下这个方法
      return create(beanName, bean, bean.getClass(), factoryMethod);
  }
  
private static ConfigurationPropertiesBean create(String name, Object instance, Class<?> type, Method factory) {
	  // 看这里,主要为了这句话
      // 判断当前bean 上面是否存在 @ConfigurationProperties 注解
      ConfigurationProperties annotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);
      // 假如为空,直接返回 null
      //这个地方就是说,虽然每个类都会走这个后置处理器,但是没有 @ConfigurationProperties 的话,到这里就结束了
      if (annotation == null) {
          return null;
      }
      Validated validated = findAnnotation(instance, type, factory, Validated.class);
      Annotation[] annotations = (validated != null) ? new Annotation[] { annotation, validated }
              : new Annotation[] { annotation };
      ResolvableType bindType = (factory != null) ? ResolvableType.forMethodReturnType(factory)
              : ResolvableType.forClass(type);
      Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);
      if (instance != null) {
          bindTarget = bindTarget.withExistingValue(instance);
      }
      return new ConfigurationPropertiesBean(name, instance, annotation, bindTarget);
  }
  
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	//然后看下bind() 方法
    bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
    return bean;
}
private void bind(ConfigurationPropertiesBean bean) {
	  // 假如 bean 为 null  直接结束了
      if (bean == null || hasBoundValueObject(bean.getName())) {
          return;
      }
      Assert.state(bean.getBindMethod() == BindMethod.JAVA_BEAN, "Cannot bind @ConfigurationProperties for bean '"
              + bean.getName() + "'. Ensure that @ConstructorBinding has not been applied to regular bean");
      try {
      	  //this.binder 是实际处理绑定的 处理类,后面会讲实在什么地方创建的
          this.binder.bind(bean);
      }
      catch (Exception ex) {
          throw new ConfigurationPropertiesBindException(bean, ex);
      }
  }
  

ConfigurationPropertiesBinder

BindResult<?> bind(ConfigurationPropertiesBean propertiesBean) {
	//获取目标类
    Bindable<?> target = propertiesBean.asBindTarget();
    //获取注解
    ConfigurationProperties annotation = propertiesBean.getAnnotation();
    BindHandler bindHandler = getBindHandler(target, annotation);
    //获取注解的 参数  也就是 ConfigurationProperties 配置的前缀 
    //getBinder()  就是获取 Binder ,  binder 的创建后面会讲
    return getBinder().bind(annotation.prefix(), target, bindHandler);
}


Binder

ConfigurationPropertiesBinder 绑定的处理 是委托给 Binder处理的

public <T> BindResult<T> bind(String name, Bindable<T> target, BindHandler handler) {
	//注意这个 name 为 前缀,就是你配置的 值
    return bind(ConfigurationPropertyName.of(name), target, handler);
}

public <T> BindResult<T> bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler) {
	//这里 , 只是一个透传
    T bound = bind(name, target, handler, false);
    return BindResult.of(bound);
}

private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, boolean create) {
    Assert.notNull(name, "Name must not be null");
    Assert.notNull(target, "Target must not be null");
    handler = (handler != null) ? handler : this.defaultBindHandler;
    Context context = new Context();
    return bind(name, target, handler, context, false, create);
}

private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, Context context,
			boolean allowRecursiveBinding, boolean create) {
    try {
        Bindable<T> replacementTarget = handler.onStart(name, target, context);
        if (replacementTarget == null) {
            return handleBindResult(name, target, handler, context, null, create);
        }
        target = replacementTarget;
        Object bound = bindObject(name, target, handler, context, allowRecursiveBinding);
        return handleBindResult(name, target, handler, context, bound, create);
    }
    catch (Exception ex) {
        return handleBindError(name, target, handler, context, ex);
    }
}


private <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler,
			Context context, boolean allowRecursiveBinding) {
    //这个方法很重要 就是在这里实现了绑定,等下回回过头讲,这是第一次  记住现在的 name 是 配置的前缀,不会得到值
    ConfigurationProperty property = findProperty(name, context);
    if (property == null && context.depth != 0 && containsNoDescendantOf(context.getSources(), name)) {
        return null;
    }
    AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
    if (aggregateBinder != null) {
        return bindAggregate(name, target, handler, context, aggregateBinder);
    }
    if (property != null) {
        try {
            return bindProperty(target, context, property);
        }
        catch (ConverterNotFoundException ex) {
            // We might still be able to bind it using the recursive binders
            Object instance = bindDataObject(name, target, handler, context, allowRecursiveBinding);
            if (instance != null) {
                return instance;
            }
            throw ex;
        }
    }
    //这里
    return bindDataObject(name, target, handler, context, allowRecursiveBinding);
}

//这个方法很重要,也相当的绕,多次使用了 函数式编程,,,  必须对 java8 的函数式编程熟悉才能搞明白
private Object bindDataObject(ConfigurationPropertyName name, Bindable<?> target, BindHandler handler,
			Context context, boolean allowRecursiveBinding) {
      if (isUnbindableBean(name, target, context)) {
          return null;
      }
      //获取目标类型
      Class<?> type = target.getType().resolve(Object.class);
      // 判断是否已经在绑定了  , 绑定的都会记录到 dataObjectBindings
      if (!allowRecursiveBinding && context.isBindingDataObject(type)) {
          return null;
      }
      //这里 创建了一个 行为函数  (函数式接口) , 注意,这个是否当前的函数还没有执行
      //他有两个参数
      DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),
              propertyTarget, handler, context, false, false);
       //这里 context.withDataObject 方法 有两个参数  1. 目标类 2.函数式接口
       //普及下知识: 函数式接口 可以用  接口,lambda,方法引用表示,这里使用的是lambada ,上面的也是
       // withDataObject 方法 东西比较式少就不看了,这个 函数式接口是 Supplier 只有一个 T  get() 方法
       //意味着,不接受参数 有一个返回值
       //withDataObject 放当前目标类型 存入 dataObjectBindings 中,然后 执行 函数式接口 的  get 方法
      return context.withDataObject(type, () -> {
      	  //然后执行到了这里
          //获取到 Binder 的 dataObjectBinders属性 , 里面包含两个实例,
          //分别为 JavaBeanBinder , ValueObjectBinder,从名字可以看出,一个处理baen,和value
          //this.dataObjectBinders 是在 创建 Binder 的时候创建的,后面会讲
          for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
          	  // 然后委托给 dataObjectBinder,我们是处理 bean 所以直接看 JavaBeanBinder,ValueObjectBinder注定得不到结果
              //注意下传参,propertyBinder 为上述提到的 函数式接口,当一个参数传递进去
              //看下  JavaBeanBinder.bind()
              Object instance = dataObjectBinder.bind(name, target, context, propertyBinder);
              if (instance != null) {
                  return instance;
              }
          }
          return null;
      });
  }
  
  
  @Override
  public <T> T bind(ConfigurationPropertyName name, Bindable<T> target, Context context,
          DataObjectPropertyBinder propertyBinder) {
      //注意  当前 name 还只是 前缀
      boolean hasKnownBindableProperties = target.getValue() != null && hasKnownBindableProperties(name, context);
      
      //这个方法很重要,我们先看下
      Bean<T> bean = Bean.get(target, hasKnownBindableProperties);
      if (bean == null) {
          return null;
      }
      BeanSupplier<T> beanSupplier = bean.getSupplier(target);
      boolean bound = bind(propertyBinder, bean, beanSupplier, context);
      return (bound ? beanSupplier.get() : null);
  }
  
  
  //Bean 的 属性有 : cached type resolvedType properties
  static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) {
      ResolvableType type = bindable.getType();
      Class<?> resolvedType = type.resolve(Object.class);
      Supplier<T> value = bindable.getValue();
      T instance = null;
      if (canCallGetValue && value != null) {
          instance = value.get();
          resolvedType = (instance != null) ? instance.getClass() : resolvedType;
      }
      if (instance == null && !isInstantiable(resolvedType)) {
          return null;
      }
      Bean<?> bean = Bean.cached;
      if (bean == null || !bean.isOfType(type, resolvedType)) {
      	  //主要看下这个构造方法
          bean = new Bean<>(type, resolvedType);
          cached = bean;
      }
      return (Bean<T>) bean;
  }
  
  Bean(ResolvableType type, Class<?> resolvedType) {
      //对属性分别赋值
      this.type = type;
      this.resolvedType = resolvedType;
      //这里
      addProperties(resolvedType);
  }
  
  private void addProperties(Class<?> type) {
  	  //目标类型不为 null 不为 Object , 我们当前是满足这个条件的
      while (type != null && !Object.class.equals(type)) {
      	  //获取目标类的所有方法
          Method[] declaredMethods = type.getDeclaredMethods();
          //获取目标类的所有属性
          Field[] declaredFields = type.getDeclaredFields();
          //这里 传入参数 所有方法和属性
          addProperties(declaredMethods, declaredFields);
          type = type.getSuperclass();
      }
  }
  
  protected void addProperties(Method[] declaredMethods, Field[] declaredFields) {
      for (int i = 0; i < declaredMethods.length; i++) {
      	  //循环所有的方法,判断是否满足添加
          //条件为  修饰符 不能是 Private, Protected,不能是抽象方法,不能是静态方法,类不能是Object,方法名不能是$开头
          if (!isCandidate(declaredMethods[i])) {
          	  //假如上述条件有一个不满足 就清除掉这个方法
              declaredMethods[i] = null;
          }
      }
      //循环符合条件的方法
      for (Method method : declaredMethods) {
      	  //看下 这个发放干了啥
          //获取所有的 get方法
          addMethodIfPossible(method, "get", 0, BeanProperty::addGetter);
          addMethodIfPossible(method, "is", 0, BeanProperty::addGetter);
      }
      for (Method method : declaredMethods) {
          //获取所有的set方法
          addMethodIfPossible(method, "set", 1, BeanProperty::addSetter);
      }
      //处理类
      for (Field field : declaredFields) {
      	  // 放入 properties 属性的中
          //Map<String, BeanProperty> properties
          //键值对的key为 属性名, BeanProperty 中包含了 这个属性的 get set 方法
          addField(field);
      }
  }
  
  
  private void addMethodIfPossible(Method method, String prefix, int parameterCount,
				BiConsumer<BeanProperty, Method> consumer) {
       //方法名要包含 出入的 前缀,并且长度大于他  就是说,这是是判断是不是  get set is 方法
      if (method != null && method.getParameterCount() == parameterCount && method.getName().startsWith(prefix)
              && method.getName().length() > prefix.length()) {
          //假如是
          //感觉方法名 截取 方法前缀 获取属性名 
          String propertyName = Introspector.decapitalize(method.getName().substring(prefix.length()));
          //设置 get set 方法  这个地方  consumer 是方法引用 是不同的方法
          consumer.accept(this.properties.computeIfAbsent(propertyName, this::getBeanProperty), method);
      }
  }
  
  //到这里获取到了 Bean 这个类,包含了这个目标类的  所有字段名称和 get  set  方法
  
  //继续看主线
  

@Override
public <T> T bind(ConfigurationPropertyName name, Bindable<T> target, Context context,
        DataObjectPropertyBinder propertyBinder) {
    boolean hasKnownBindableProperties = target.getValue() != null && hasKnownBindableProperties(name, context);
    // Bean.get() 方法上面已经看过
    Bean<T> bean = Bean.get(target, hasKnownBindableProperties);
    if (bean == null) {
        return null;
    }
    //这个只是获取了一个函数式接口,还没执行
    BeanSupplier<T> beanSupplier = bean.getSupplier(target);
    //这里  ,  propertyBinder beanSupplier 函数式接口 
    boolean bound = bind(propertyBinder, bean, beanSupplier, context);
    return (bound ? beanSupplier.get() : null);
}


private <T> boolean bind(DataObjectPropertyBinder propertyBinder, Bean<T> bean, BeanSupplier<T> beanSupplier,
			Context context) {
    boolean bound = false;
    //循环说有的类  , 应该还记得  beanProperty 就是一个 类的封装信息,包含属性名,get  set  方法
    for (BeanProperty beanProperty : bean.getProperties().values()) {
    	//这里 
        bound |= bind(beanSupplier, propertyBinder, beanProperty);
        context.clearConfigurationProperty();
    }
    return bound;
}

private <T> boolean bind(BeanSupplier<T> beanSupplier, DataObjectPropertyBinder propertyBinder,
			BeanProperty property) {
    // 属性名
    String propertyName = property.getName();
    // 属性类型
    ResolvableType type = property.getType();
    Supplier<Object> value = property.getValue(beanSupplier);
    // 属性注解
    Annotation[] annotations = property.getAnnotations();
    //调用了 propertyBinder 函数式接口 , 传递了这么远,终于要执行了 
    //传递了 类型 和 Bindable
    Object bound = propertyBinder.bindProperty(propertyName,
            Bindable.of(type).withSuppliedValue(value).withAnnotations(annotations));
    if (bound == null) {
        return false;
    }
    //这个 获取到 这个属性的 值,假如存在 set 方法, 将其值放入 value 中
    //也就是说,假如没有set 方法 是没有办法赋值的
    if (property.isSettable()) {
        property.setValue(beanSupplier, bound);
    }
    else if (value == null || !bound.equals(value.get())) {
        throw new IllegalStateException("No setter found for property: " + property.getName());
    }
    return true;
}

//还记得这句代码吧
//结合上面的方法  name 为前缀,propertyName为列名, 拼一起是 配置名称
DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),
				propertyTarget, handler, context, false, false);
                
 
//又来到了这个方法,上次的 name 是前缀,这次是 配置名称
private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, Context context,
          boolean allowRecursiveBinding, boolean create) {
      try {
          Bindable<T> replacementTarget = handler.onStart(name, target, context);
          if (replacementTarget == null) {
              return handleBindResult(name, target, handler, context, null, create);
          }
          target = replacementTarget;
          //这里
          Object bound = bindObject(name, target, handler, context, allowRecursiveBinding);
          return handleBindResult(name, target, handler, context, bound, create);
      }
      catch (Exception ex) {
          return handleBindError(name, target, handler, context, ex);
      }
  }
  
  
 private <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler,
			Context context, boolean allowRecursiveBinding) {
      //这个方法 上面提到过 会讲,重点  先看下
      ConfigurationProperty property = findProperty(name, context);
      if (property == null && context.depth != 0 && containsNoDescendantOf(context.getSources(), name)) {
          return null;
      }
      AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
      if (aggregateBinder != null) {
          return bindAggregate(name, target, handler, context, aggregateBinder);
      }
      if (property != null) {
          try {
              return bindProperty(target, context, property);
          }
          catch (ConverterNotFoundException ex) {
              // We might still be able to bind it using the recursive binders
              Object instance = bindDataObject(name, target, handler, context, allowRecursiveBinding);
              if (instance != null) {
                  return instance;
              }
              throw ex;
          }
      }
      return bindDataObject(name, target, handler, context, allowRecursiveBinding);
  }
  
  
private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {
    if (name.isEmpty()) {
        return null;
    }
    // context.getSources() Binder 中的 sources 属性
    //实现类为 SpringConfigurationPropertySources  实现了 Iterable 接口,意味着 这个类可以遍历 
    //所以不要奇怪这个属性为啥可以 for 
    //这里想看下 SpringConfigurationPropertySources 的 iterator 方法 返回的啥吧,要不然也是懵逼的,
    // iterator 方法返回的就是 next() 方法的返回 就是 for 每次的值
    for (ConfigurationPropertySource source : context.getSources()) {
        ConfigurationProperty property = source.getConfigurationProperty(name);
        if (property != null) {
            return property;
        }
    }
    return null;
}

//位置 org.springframework.boot.context.properties.source.SpringConfigurationPropertySources.iterator()
@Override
public Iterator<ConfigurationPropertySource> iterator() {
	//好吧,发现实际是调用其属性 sources 的 iterator()
    //this::adapt 要注意下, 后面会发现是使用 MutablePropertySources.
    //但是MutablePropertySources.propertySourceList只有两个元素,
    //就是因为  this::adapt  才能那种所有的 数据源
    //内容很多,不看了,大概知道这个意思就行
    return new SourcesIterator(this.sources.iterator(), this::adapt);
}

//位置 org.springframework.core.env.MutablePropertySources.iterator()
@Override
public Iterator<PropertySource<?>> iterator() {
	//发现最后使用的 是 其属性  propertySourceList
    //记住了 那个 for 循环实际上是循环的  propertySourceList 这个集合
    return this.propertySourceList.iterator();
}


private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {
    if (name.isEmpty()) {
        return null;
    }
    // context.getSources() Binder 中的 sources 属性
    //实现类为 SpringConfigurationPropertySources  实现了 Iterable 接口,意味着 这个类可以遍历 
    //所以不要奇怪这个属性为啥可以 for 
    //这里想看下 SpringConfigurationPropertySources 的 iterator 方法 返回的啥吧,要不然也是懵逼的,
    // iterator 方法返回的就是 next() 方法的返回 就是 for 每次的值
    for (ConfigurationPropertySource source : context.getSources()) {
    	//获取值
        //循环着所有的配置文件,直到找到值结束
        //所以说赋值的过程结束了,我们现在要看看 数据源的来源
        ConfigurationProperty property = source.getConfigurationProperty(name);
        if (property != null) {
            return property;
        }
    }
    return null;
}

数据来源

1. 上面已经知道数据源实在 org.springframework.core.env.MutablePropertySources.propertySourceList 中保存的
2. 注意,下面的代码 , 很多都是倒叙的
//看下数据来源
//MutablePropertySources 是 SpringConfigurationPropertySources.sources属性
//代码如下
SpringConfigurationPropertySources(Iterable<PropertySource<?>> sources) {
    Assert.notNull(sources, "Sources must not be null");
    this.sources = sources;
}

//现在知道了MutablePropertySources 是在  SpringConfigurationPropertySources() 构造方法中赋值的,那就看看什么什么调用的这个方法
//代码如下:
//这个方法 是在 处理数据绑定的时候调用的,上面不是提到过吗,数据绑定是委托给ConfigurationPropertiesBinder 这个类处理的
//当前位置  ConfigurationPropertiesBinder
private Binder getBinder() {
    if (this.binder == null) {
    	//主要看下第一个参数,就是 SpringConfigurationPropertySources 
        //所以我们要看下 getConfigurationPropertySources(),是日如何拿到数据的
        this.binder = new Binder(getConfigurationPropertySources(), getPropertySourcesPlaceholdersResolver(),
                getConversionService(), getPropertyEditorInitializer(), null,
                ConfigurationPropertiesBindConstructorProvider.INSTANCE);
    }
    return this.binder;
}

//当前位置  ConfigurationPropertiesBinder
private Iterable<ConfigurationPropertySource> getConfigurationPropertySources() {
    return ConfigurationPropertySources.from(this.propertySources);
}

//当前位置  ConfigurationPropertiesBinder
public static Iterable<ConfigurationPropertySource> from(Iterable<PropertySource<?>> sources) {
	//这个传入的参数就是 MutablePropertySources 
    //最后发现 MutablePropertySources 竟然是 ConfigurationPropertiesBinder 的 propertySources 属性
    return new SpringConfigurationPropertySources(sources);
}

//接下来我们要看下 ConfigurationPropertiesBinder.propertySources 属性是在什么地方被赋值的
//当前位置  ConfigurationPropertiesBinder
ConfigurationPropertiesBinder(ApplicationContext applicationContext) {
    this.applicationContext = applicationContext;
    //发现是在这个地方赋值的 
    //那就看下 getPropertySources() 干了啥
    //注意,PropertySourcesDeducer() 构造方法,传递了 applicationContext
    this.propertySources = new PropertySourcesDeducer(applicationContext).getPropertySources();
    this.configurationPropertiesValidator = getConfigurationPropertiesValidator(applicationContext);
    this.jsr303Present = ConfigurationPropertiesJsr303Validator.isJsr303Present(applicationContext);
}

//当前位置 org.springframework.boot.context.properties.PropertySourcesDeducer.getPropertySources()
PropertySources getPropertySources() {
		//数据来源 
        //PropertySourcesPlaceholderConfigurer 是个 bean工厂 的后置处理器
      PropertySourcesPlaceholderConfigurer configurer = getSinglePropertySourcesPlaceholderConfigurer();
      if (configurer != null) {
          // 发现响应的数据是从configurer来的  
          return configurer.getAppliedPropertySources();
      }
      MutablePropertySources sources = extractEnvironmentPropertySources();
      Assert.state(sources != null,
              "Unable to obtain PropertySources from PropertySourcesPlaceholderConfigurer or Environment");
      return sources;
  }
  
  //当前位置 PropertySourcesDeducer.getSinglePropertySourcesPlaceholderConfigurer()
  //这个方法 就是获取 PropertySourcesPlaceholderConfigurer 这个 bean工厂后置处理器
  private PropertySourcesPlaceholderConfigurer getSinglePropertySourcesPlaceholderConfigurer() {
		// Take care not to cause early instantiation of all FactoryBeans
		Map<String, PropertySourcesPlaceholderConfigurer> beans = this.applicationContext
				.getBeansOfType(PropertySourcesPlaceholderConfigurer.class, false, false);
		if (beans.size() == 1) {
			return beans.values().iterator().next();
		}
		if (beans.size() > 1 && logger.isWarnEnabled()) {
			logger.warn("Multiple PropertySourcesPlaceholderConfigurer beans registered " + beans.keySet()
					+ ", falling back to Environment");
		}
		return null;
	}
    
//到目前位置  我们应该知道了,数据的来源是在:
//bean工厂后置处理器  PropertySourcesPlaceholderConfigurer.appliedPropertySources 属性.
//接下来就看看这个数据 是什么时候被添加进去的.


//当前位置  PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(ConfigurableListableBeanFactory)
//postProcessBeanFactory 方法是 bean工厂后置处理器的顶层接口的方法
//假如对  bean工厂后置处理器不明白 可以去看以前的文章 
//当前方法 :
//PropertySourcesPlaceholderConfigurer 在 执行的时候 执行了当前方法,是在 AbstractApplicationContext.refresh()中执行的
//但是 数据源是在 environment 中保存的,现在就要看下 environment 是在什么时候赋值的
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
	//environment 是 ioc 容器的属性
    if (this.propertySources == null) {
        this.propertySources = new MutablePropertySources();
        if (this.environment != null) {
        	//这里  
            this.propertySources.addLast(
                new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
                    @Override
                    @Nullable
                    public String getProperty(String key) {
                        return this.source.getProperty(key);
                    }
                }
            );
        }
        try {
            PropertySource<?> localPropertySource =
                    new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
            if (this.localOverride) {
                this.propertySources.addFirst(localPropertySource);
            }
            else {
                this.propertySources.addLast(localPropertySource);
            }
        }
        catch (IOException ex) {
            throw new BeanInitializationException("Could not load properties", ex);
        }
    }

    processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
    //发现 属性是在这里赋值的  
    this.appliedPropertySources = this.propertySources;
}


//这个方法 是在  一个bean ioc初始化完成的时候.执行的,具体位置在:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(String, Object, RootBeanDefinition)
private void invokeAwareInterfaces(Object bean) {
	//当前bean工厂后置处理器 实现了 EnvironmentAware接口
    if (bean instanceof EnvironmentAware) {
    	//这里给这个类赋值了 ioc 容器的环境 Environment
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

//总结就是 数据源是在  applicationContext.environment中保存的,接下来就要看看  applicationContext.environment是怎么来的
//applicationContext.environment
//当前位置 org.springframework.boot.SpringApplication.run(String...)
//这个方法就是 springboot 的启动入口
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        //本文主要关注这行代码 
        //直接翻译,准备 环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        listeners.started(context);
        callRunners(context, applicationArguments);
    }
    ...................................
    return context;
}


private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments) {
    // Create and configure the environment
    //这里是记载一些系统的配置文件
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    ConfigurationPropertySources.attach(environment);
    //这里 大概看的出是要执行监听器
    listeners.environmentPrepared(environment);
    bindToSpringApplication(environment);
    if (!this.isCustomEnvironment) {
        environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                deduceEnvironmentClass());
    }
    ConfigurationPropertySources.attach(environment);
    return environment;
}


@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
	//这里发布了一个 ApplicationEnvironmentPreparedEvent 事件
    this.initialMulticaster
            .multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}

//接下来就是spring 监听器的 源码了  大致看下
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    //这里的getApplicationListeners方法是获取 监听了当前事件 的监听器
    //具体只能获取的就不看了,大致就是 你添加的监听器的生活,spring 会以 key(事件) - list<监听器> 这种来存储
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        }
        else {
        	//循环执行 监听器
            invokeListener(listener, event);
        }
    }
}


@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
    	//执行监听器的 onApplicationEvent 方法
        // 我们需要关注的监听器是 ConfigFileApplicationListener
        listener.onApplicationEvent(event);
    }
    catch (ClassCastException ex) {
        String msg = ex.getMessage();
        if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
            // Possibly a lambda-defined listener which we could not resolve the generic event type for
            // -> let's suppress the exception and just log a debug message.
            Log logger = LogFactory.getLog(getClass());
            if (logger.isTraceEnabled()) {
                logger.trace("Non-matching event type for listener: " + listener, ex);
            }
        }
        else {
            throw ex;
        }
    }
}

//当前位置 ConfigFileApplicationListener.onApplicationEvent(ApplicationEvent)
@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
    	//这里
        onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
    }
    if (event instanceof ApplicationPreparedEvent) {
        onApplicationPreparedEvent(event);
    }
}

private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
      List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
      postProcessors.add(this);
      AnnotationAwareOrderComparator.sort(postProcessors);
      for (EnvironmentPostProcessor postProcessor : postProcessors) {
      		//这里循环一些处理器.
            //当前类也是处理器
            //主要就是看当前类的 postProcessEnvironment
          postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
      }
  }
  
  //
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    addPropertySources(environment, application.getResourceLoader());
}

protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
    RandomValuePropertySource.addToEnvironment(environment);
    // 看下 这行代码
    new Loader(environment, resourceLoader).load();
}


//当前位置 : org.springframework.boot.context.config.ConfigFileApplicationListener.Loader.load()
void load() {
    FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY,
            (defaultProperties) -> {
                this.profiles = new LinkedList<>();
                this.processedProfiles = new LinkedList<>();
                this.activatedProfiles = false;
                this.loaded = new LinkedHashMap<>();
                initializeProfiles();
                while (!this.profiles.isEmpty()) {
                    Profile profile = this.profiles.poll();
                    if (isDefaultProfile(profile)) {
                        addProfileToEnvironment(profile.getName());
                    }
                    //这里 
                    load(profile, this::getPositiveProfileFilter,
                            addToLoaded(MutablePropertySources::addLast, false));
                    this.processedProfiles.add(profile);
                }
                load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
                addLoadedPropertySources();
                applyActiveProfiles(defaultProperties);
            });
}

private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
	// getSearchLocations 获取的是从哪些路径下加载配置文件
    // [file:./config/, file:./config/*/, file:./, classpath:/config/, classpath:/]
    getSearchLocations().forEach((location) -> {
        boolean isDirectory = location.endsWith("/");
        //获取 
        Set<String> names = isDirectory ? getSearchNames() : NO_SEARCH_NAMES;
        names.forEach((name) -> load(location, name, profile, filterFactory, consumer));
    });
}

private void load(String location, String name, Profile profile, DocumentFilterFactory filterFactory,
				DocumentConsumer consumer) {
    if (!StringUtils.hasText(name)) {
    	//this.propertySourceLoaders 是对不同文件的处理器  propertise  yml 
        for (PropertySourceLoader loader : this.propertySourceLoaders) {
            if (canLoadFileExtension(loader, location)) {
            	//这里
                load(loader, location, profile, filterFactory.getDocumentFilter(profile), consumer);
                return;
            }
        }
        throw new IllegalStateException("File extension of config file location '" + location
                + "' is not known to any PropertySourceLoader. If the location is meant to reference "
                + "a directory, it must end in '/'");
    }
    Set<String> processed = new HashSet<>();
    for (PropertySourceLoader loader : this.propertySourceLoaders) {
        for (String fileExtension : loader.getFileExtensions()) {
            if (processed.add(fileExtension)) {
                loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory,
                        consumer);
            }
        }
    }
}


//结束