6.IOC容器源码解读—核心流程原理

IOC容器源码解读—核心流程原理

IOC容器源码解读

IOC容器核心流程

Spring IOC容器核心方法在于Refresh方法,这个方法里面完成了Spring初始化、准备Bean、实例化Bean及扩展功能的实现。所以学明白它非常重要。

带着问题
  1. 这个方法做什么用的?

  2. 它是怎么完成这个功能的?

  3. 为什么要这样实现?

  4. 有哪些值得学习借鉴的地方?

Refresh方法
在哪里定义的?

ConfigurableApplicationContext#refresh

​ 这个方法用来加载刷新配置,这些配置可能来自,java配置、xml文件、properties文件,关系型数据库,或者其他格式。

​ 作为一个启动方法,它应当在初始化失败后销毁已经创建了的单例,防止占着资源不用。也就是说调用这个方法,要么没有所有的单例被创建、要么没有没有单例对象创建。

/**
* Load or refresh the persistent representation of the configuration,
which
* might be from Java-based configuration, an XML file, a properties
file, a
* relational database schema, or some other format.
* 这个方法用来加载刷新配置,这些配置可能来自,java配置、xml文件、properties文件,
关系型数据库,或者其他格式。
*
* <p>As this is a startup method, it should destroy already created
singletons
* if it fails, to avoid dangling resources. In other words, after
invocation
* of this method, either all or no singletons at all should be
instantiated.
* 作为一个启动方法,它应当在初始化失败后销毁已经创建了的单例,防止占着资源不用。
* 也就是说调用这个方法,要么没有所有的单例被创建、要么没有没有单例对象创建。
*
* @throws BeansException if the bean factory could not be initialized
* Bean工厂不能被初始化,抛出BeansException异常
*
* @throws IllegalStateException if already initialized and multiple
refresh
* attempts are not supported
* bean工厂已经被初始化了,但是不支持多次刷新,抛出IllegalStateException异常
*/
void refresh() throws BeansException, IllegalStateException;

经过对该方法的注解解读,发现该方法提供了从加载配置单例bean创建的功能。

在哪里实现的?

AbstractApplicationContext#refresh

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

在AbstractApplicationContext中的实现,调用了10多个方法,来完成该功能。

哪些类使用?

打开ConfigurableApplicationContext#refresh方法,Ctrl+G就能找到相关调用方法的地方,可以看到基本都在ApplicationContext的实现子类中使用。

image-20241220210824178

用法示例

// 除了new各种ApplicationContext实现子类,还可以手动调用
GenericApplicationContext context3 = new GenericApplicationContext();
new XmlBeanDefinitionReader(context3).
loadBeanDefinitions("classpath:application.xml");
new ClassPathBeanDefinitionScanner(context3).scan("edu.dongnao.courseware");
// 一定要刷新
context3.refresh();

refresh方法有13个方法一定会被调用到,这里也就包含了13个步骤逻辑,接下来逐一进行分析。

IOC容器刷新整体流程

这13个方法中,每一个方法都是一个步骤。

梳理如图:

image-20241220211045551

prepareRefresh()
/**
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 */
protected void prepareRefresh() {
   // Switch to active.
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
         logger.trace("Refreshing " + this);
      }
      else {
         logger.debug("Refreshing " + getDisplayName());
      }
   }

   // Initialize any placeholder property sources in the context environment.
   initPropertySources();

   // Validate that all properties marked as required are resolvable:
   // see ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();

   // Store pre-refresh ApplicationListeners...
   if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   }
   else {
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   this.earlyApplicationEvents = new LinkedHashSet<>();
}
obtainFreshBeanFactory()

告诉子类刷新内部的BeanFactory,其实就是配置用户属性、加载Bean定义,并返回刷新后的Bean厂。prepareBeanFacotry方法又由两个抽象方法构成,交给子类实现。也就是子类必定含有一个BeanFactory实例,并且还需要提供刷新方法、返回BeanFactory实例方法。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

对应的实现有AbstractRefreshableApplicationContext、GenericApplicationContext两个类。

image-20241220212721696

  • AbstractRefreshableApplicationContext

    AbstractRefreshableApplicationContext中实现的刷新方法,可以被多次调用执行。

    /**
     * This implementation performs an actual refresh of this context's underlying
     * bean factory, shutting down the previous bean factory (if any) and
     * initializing a fresh bean factory for the next phase of the context's lifecycle.
     */
    @Override
    protected final void refreshBeanFactory() throws BeansException {
       if (hasBeanFactory()) {// 存在Bean工厂则销毁单例bean,释放资源
          destroyBeans();
          closeBeanFactory();
       }
       try {
           // 创建DefalutListableBeanFactory实例
          DefaultListableBeanFactory beanFactory = createBeanFactory();
           // 设置ID
          beanFactory.setSerializationId(getId());
           // 自定义Bean工厂属性:Bean定义重写、循环引用等配置
          customizeBeanFactory(beanFactory);
           // 等待子类实现的,向bean工厂注册Bean定义
          loadBeanDefinitions(beanFactory);
           // 持有bean工厂实例,以便在getBeanFactory方法中返回出去
          this.beanFactory = beanFactory;
       }
       catch (IOException ex) {
          throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
       }
    }
    

    bean定义的加载注册前面已经学习过了,到这里就能过连上去了。

  • GenericApplicationContext

    GenericApplicationContext中的刷新方法,只能被调用一次,被Atomic的refreshed状态控制着。

    /**
     * Do nothing: We hold a single internal BeanFactory and rely on callers
     * to register beans through our public methods (or the BeanFactory's).
     * @see #registerBeanDefinition
     */
    @Override
    protected final void refreshBeanFactory() throws IllegalStateException {
       if (!this.refreshed.compareAndSet(false, true)) {
          throw new IllegalStateException(
                "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
       }
       this.beanFactory.setSerializationId(getId());
    }
    

    刷新的方法也很简单,只是设置了一个ID。那么此时应该有几个疑问。

    • BeanFactory什么时候创建的?

      构造函数中

      /**
       * Create a new GenericApplicationContext.
       * @see #registerBeanDefinition
       * @see #refresh
       */
      public GenericApplicationContext() {
         this.beanFactory = new DefaultListableBeanFactory();
      }
      
    • 此时的BeanFactory里面都有什么呢?

      回头想想,注解方式的Bean定义加载过程都装载了什么。BeanFactoryPostProcessor、BeanPostProcessor、ApplicationListener。

prepareBeanFactory(beanFactory)

此时,Bean定义加载完成,Bean工厂已经被构建了,加下来做的事情就是给Bean工厂对象,注入执行后续东西需要的依赖,比如ClassLoader、BeanPostProcessor、环境相关的实例Bean。

AbstractApplicationContext#prepareBeanFactory方法的实现如下:

/**
 * Configure the factory's standard context characteristics,
 * such as the context's ClassLoader and post-processors.
 * @param beanFactory the BeanFactory to configure
 */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
    // 给bean工作准备ClassLoader、SPL表达是解析器、属性编辑注册器等
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
    // 向BeanFactory注册ApplicationContextAwareProcessor
	// 后面的6种Aware忽略它们的自动依赖注入,为什么?
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
    // 依赖需要使用的bean,IOC容器自己的多角色身份 @Autowried方式获得下列类型bean
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
    // 注入ApplicationListeners接口实现的发现处理器,同时带有销毁、bean定义混合的实现。
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
    // 这些参数的应用顺序是怎么样的?
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
       // properties配置文件
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
       // 操作系统环境变量:JAVA_HOME等
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

后面的6种Aware忽略它们的自动依赖注入,为什么?

  • BeanPostProcessor的注入

ApplicationContextAwareProcessor、ApplicationListenerDetector、LoadTimeWeaverAwareProcessor,查看其中一个。

ApplicationContextAwareProcessor中的实现

ApplicationContextAwareProcessor是BeanPostProcessor,方法postProcessBeforeInitialization会在初始化之前执行,内部代码如下:


/**
 * 会在bean初始化之前执行,执行时判断bean是否属于EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware这六种Aware,如果不属于,执行invokeAwareInterfaces方法,调用这六种Aware的set方法赋值,因此beanFactory.ignoreDependencyInterface需要添加这6种Aware忽略依赖,不需要再次处理这6种依赖了
 */
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
         bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
         bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
      return bean;
   }

   AccessControlContext acc = null;

   if (System.getSecurityManager() != null) {
      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
   }

   if (acc != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareInterfaces(bean);
         return null;
      }, acc);
   }
   else {
      invokeAwareInterfaces(bean);
   }

   return bean;
}

// 将beanFactory注入给上述的6种Aware
private void invokeAwareInterfaces(Object bean) {
   if (bean instanceof EnvironmentAware) {
      ((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);
   }
}
  • 手动注册环境相关单例Bean

    environment、systemProperties、systemEnvironment

postProcessBeanFactory(beanFactory)

处理BeanFactory,暂时在spring.context包中没有实现

invokeBeanFactoryPostProcessors(beanFactory)
/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   // 最重要的处理在委托里面实现
// getBeanFactoryPostProcessors()获取的是容器里面的列表属性,这个属性没有机会给外部去注入BeanFactoryPostProcessor对象。因为ApplicationContext子类在构造函数中调用了refresh方法。所以这里是个空值。
// 外部又是如何加入进去的呢?看看委托里面的实现
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法解读

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}
  • IOC容器与BeanFactoryPostProcessor的关系

    回顾前面BeanFactoryPostProcessor与容器的结构图:

    image-20241221103005329

  • BeanFactoryPostProcessors的调用处理

    PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors分析

    拆分处理:registryProcessors、regularPostProcessors

    排序处理:PriorityOrdered、Ordered

    多次调用BeanFactoryPostProcessors的分析:在调用BeanFactoryPostProcessors过程中,还会产生BeanFactoryPostProcessors,直到所有的BeanFactoryPostProcessors处理完毕。

registerBeanPostProcessors(beanFactory)

此时Bean定义加载完成,Bean工厂完成了刷新实例化,通过了BeanFactoryProcessor修整了Bean定义,接下来注册BeanPostProcessors。

/**
 * Instantiate and register all BeanPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before any instantiation of application beans.
 */
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

PostProcessorRegistrationDelegate.registerBeanPostProcessors

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
  • 注册BeanPostProcessor的处理

    整体处理逻辑与BeanFactroyPostProcessor的处理一样,排序然后调用的处理。

    1. priorityOrderedPostProcessors

    2. orderedPostProcessors

    3. nonOrderedPostProcessors

    4. internalPostProcessors

    5. ApplicationListenerDetector

initMessageSource()

此时BenPostProcessor都已经注册完成,下一步准备资源国际化的事宜

/**
 * Initialize the MessageSource.
 * Use parent's if none defined in this context.
 */
protected void initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //判断beanFactory中是否包含一个为“messageSource”的bean定义,包含直接使用
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
      // Make MessageSource aware of parent MessageSource.
      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
         if (hms.getParentMessageSource() == null) {
            // Only set parent context as parent MessageSource if no parent MessageSource
            // registered already.
            hms.setParentMessageSource(getInternalParentMessageSource());
         }
      }
      if (logger.isTraceEnabled()) {
         logger.trace("Using MessageSource [" + this.messageSource + "]");
      }
   }
    //判断beanFactory中是否包含一个为“messageSource”的bean定义,不包含,创建一个默认的,并将这个对象作为一个单例bean注册到beanfactory中
   else {
      // Use empty MessageSource to be able to accept getMessage calls.
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
      }
   }
}
  • 使用示例

    第一步:在resources,右键添加一个Resource Bundle,

    image-20241221104227038image-20241221104313149

    image-20241221104354219

    创建了一个英文的message.properties和一个中文的message_zh_CN.properties

    image-20241221104458758

    第二步:创建一个bean

@MyComponetAnno
public class MessageBean {

   @Autowired
   private ApplicationContext applicationContext;

   public MessageBean() {
      System.out.println("-----------------Abean 被实例化了。。。。。。。。。");
   }

   public void doSomething() {
      System.out.println(this + " do something .....my.love="
            + this.applicationContext.getEnvironment().getProperty("my.love"));
      System.out
            .println("-----------project.name=" + 
                  this.applicationContext.getMessage("project.name", null, Locale.CHINA));
   }
}

​ 第三步:增加配置类

@Configuration
@PropertySource("classpath:/application.properties")
public class MessageConfiguration {
   //必须和上文源码中的MESSAGE_SOURCE_BEAN_NAME的名字一致
   @Bean("messageSource")
   public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
      ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
      rms.setBasename("message");//设置Resource Bundle的名字
      return rms;
   }
}

第四步:启动测试

public class MessageStarter {

   public static void main(String[] args) {
      // 注解方式,指定扫描的包
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
            "edu.dongnao.courseware.spring.message");
      MessageBean bean = context.getBean(MessageBean.class);
      bean.doSomething();
      context.close();

   }
}
initApplicationEventMulticaster()

初始化事件多播器

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //判断是否有名字为:applicationEventMulticaster,有直接通容器中获取
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
        //判断是否有名字为:applicationEventMulticaster,没有创建一个SimpleApplicationEventMulticaster
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}
onRefresh()

处理刷新时间,暂时在spring.context包中没有实现

registerListeners()

国际化资源准备完毕,接下来,检查事件监听器,并注册到事件传播器上。

/**
 * Add beans that implement ApplicationListener as listeners.
 * Doesn't affect other listeners, which can be added without being beans.
 * 在不生成Bean对象的情况下添加ApplicationListener bean作为监听器。
 */
protected void registerListeners() {
   // Register statically specified listeners first.
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let post-processors apply to them!
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // Publish early application events now that we finally have a multicaster...
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}
  • 事件广播器执行方法

    SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType)

    @Override
    public void multicastEvent(ApplicationEvent event) {
       multicastEvent(event, resolveDefaultEventType(event));
    }
    
    @Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
       ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
       Executor executor = getTaskExecutor();
       for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
          if (executor != null) {
             executor.execute(() -> invokeListener(listener, event));
          }
          else {
             invokeListener(listener, event);
          }
       }
    }
    

注意:发布事件,如果事件监听器,没有指定支持的事件类型,没以后指定支持的事件源类型,或者实现ApplicationListener这个接口,没有指定泛型类型,那么就会监听所有的事件

finishBeanFactoryInitialization(beanFactory)

完成bean工厂的初始化,将bean工厂中,非懒加载的单例bean进行实例化。

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}
finishRefresh()
/**
 * Finish the refresh of this context, invoking the LifecycleProcessor's
 * onRefresh() method and publishing the
 * {@link org.springframework.context.event.ContextRefreshedEvent}.
 */
protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();

   // Initialize lifecycle processor for this context.
   initLifecycleProcessor();

   // Propagate refresh to lifecycle processor first.
   getLifecycleProcessor().onRefresh();

   // Publish the final event.
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}
resetCommonCaches()
/**
 * Reset Spring's common reflection metadata caches, in particular the
 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
 * and {@link CachedIntrospectionResults} caches.
 * @since 4.2
 * @see ReflectionUtils#clearCache()
 * @see AnnotationUtils#clearCache()
 * @see ResolvableType#clearCache()
 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
 */
protected void resetCommonCaches() {
   ReflectionUtils.clearCache();
   AnnotationUtils.clearCache();
   ResolvableType.clearCache();
   CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
IOC容器关闭

AbstractApplicationContext#close

AbstractApplicationContext#registerShutdownHook

AbstractApplicationContext#doClose

public void registerShutdownHook() {
   if (this.shutdownHook == null) {
      // No shutdown hook registered yet.
      this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
         @Override
         public void run() {
            synchronized (startupShutdownMonitor) {
               doClose();
            }
         }
      };
      //钩子
      Runtime.getRuntime().addShutdownHook(this.shutdownHook);
   }
}

Spring中的properties解析

配置方式

第一种,在application.xml中配置
<bean id="propertyConfig" class="com.kungyu.custom.element.PropertySourcesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:application-dev.properties</value>
                <value>classpath:application-test.properties</value>
            </list>
        </property>
    </bean>
<context:property-placeholder location="application.properties"></context:property-placeholder>
第二种,通过@Bean方式
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
 
 
@Component
public class BeanConfig implements ResourceLoaderAware {
 
  private ResourceLoader resourceLoader;
 
    @Bean
    public PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {       
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        
       propertySourcesPlaceholderConfigurer.setLocation(resourceLoader.getResource("application.properties"));
        return propertySourcesPlaceholderConfigurer;
    }
 
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}
第三种,通过@PropertySource(“classpath:/application.properties”)
@Configuration
@PropertySource("classpath:/application.properties")
public class MessageConfiguration {

	//省略......
}

解析方式

第一种解析方式

自定义注解,通过命名空间找到ContextNamespaceHandler类

image-20241221115628341

ContextNamespaceHandler内部实现:

public class ContextNamespaceHandler extends NamespaceHandlerSupport {

   @Override
   public void init() {
      registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
      registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
      registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
      registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
      registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
      registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
      registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
      registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
   }

}

找到PropertyPlaceholderBeanDefinitionParser这个BeanDefinitionParser解析器,将标签转换为bean定义

调用父类的AbstractBeanDefinitionParser#parse

public final BeanDefinition parse(Element element, ParserContext parserContext) {
    //关键获取BeanDefinition定义
   AbstractBeanDefinition definition = parseInternal(element, parserContext);
   if (definition != null && !parserContext.isNested()) {
      try {
         String id = resolveId(element, definition, parserContext);
         if (!StringUtils.hasText(id)) {
            parserContext.getReaderContext().error(
                  "Id is required for element '" + parserContext.getDelegate().getLocalName(element)
                        + "' when used as a top-level tag", element);
         }
         String[] aliases = null;
         if (shouldParseNameAsAliases()) {
            String name = element.getAttribute(NAME_ATTRIBUTE);
            if (StringUtils.hasLength(name)) {
               aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
            }
         }
         BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
          //注册BeanDefinition定义
         registerBeanDefinition(holder, parserContext.getRegistry());
         if (shouldFireEvents()) {
            BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
            postProcessComponentDefinition(componentDefinition);
            parserContext.registerComponent(componentDefinition);
         }
      }
      catch (BeanDefinitionStoreException ex) {
         String msg = ex.getMessage();
         parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element);
         return null;
      }
   }
   return definition;
}

获取BeanDefinition定义AbstractSingleBeanDefinitionParser#parseInternal

@Override
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
   BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
   String parentName = getParentName(element);
   if (parentName != null) {
      builder.getRawBeanDefinition().setParentName(parentName);
   }
    //关键获取class类
   Class<?> beanClass = getBeanClass(element);
   if (beanClass != null) {
      builder.getRawBeanDefinition().setBeanClass(beanClass);
   }
   else {
      String beanClassName = getBeanClassName(element);
      if (beanClassName != null) {
         builder.getRawBeanDefinition().setBeanClassName(beanClassName);
      }
   }
   builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
   BeanDefinition containingBd = parserContext.getContainingBeanDefinition();
   if (containingBd != null) {
      // Inner bean definition must receive same scope as containing bean.
      builder.setScope(containingBd.getScope());
   }
   if (parserContext.isDefaultLazyInit()) {
      // Default-lazy-init applies to custom bean definitions as well.
      builder.setLazyInit(true);
   }
   doParse(element, parserContext, builder);
   return builder.getBeanDefinition();
}

getBeanClass回到PropertyPlaceholderBeanDefinitionParser#getBeanClass内部实现

class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {

   private static final String SYSTEM_PROPERTIES_MODE_ATTRIBUTE = "system-properties-mode";

   private static final String SYSTEM_PROPERTIES_MODE_DEFAULT = "ENVIRONMENT";

	//返回PropertyPlaceholderConfigurer
   @Override
   @SuppressWarnings("deprecation")
   protected Class<?> getBeanClass(Element element) {
      // As of Spring 3.1, the default value of system-properties-mode has changed from
      // 'FALLBACK' to 'ENVIRONMENT'. This latter value indicates that resolution of
      // placeholders against system properties is a function of the Environment and
      // its current set of PropertySources.
       //如果标签的system-properties-mode为“ENVIRONMENT”时,返回PropertySourcesPlaceholderConfigurer
      if (SYSTEM_PROPERTIES_MODE_DEFAULT.equals(element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE))) {
         return PropertySourcesPlaceholderConfigurer.class;
      }

      // The user has explicitly specified a value for system-properties-mode: revert to
      // PropertyPlaceholderConfigurer to ensure backward compatibility with 3.0 and earlier.
      // This is deprecated; to be removed along with PropertyPlaceholderConfigurer itself.
       //返回PropertyPlaceholderConfigurer
      return org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class;
   }

   @Override
   protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
      super.doParse(element, parserContext, builder);

      builder.addPropertyValue("ignoreUnresolvablePlaceholders",
            Boolean.valueOf(element.getAttribute("ignore-unresolvable")));

      String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
      if (StringUtils.hasLength(systemPropertiesModeName) &&
            !systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {
         builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_" + systemPropertiesModeName);
      }

      if (element.hasAttribute("value-separator")) {
         builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
      }
      if (element.hasAttribute("trim-values")) {
         builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
      }
      if (element.hasAttribute("null-value")) {
         builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
      }
   }

}

PropertySourcesPlaceholderConfigurer 是一个BeanFactoryPostProcessor在IOC核心流程的第四步中执行

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
   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;
}

mergeProperties()方法实现

/**
 * Return a merged Properties instance containing both the
 * loaded properties and properties set on this FactoryBean.
 */
protected Properties mergeProperties() throws IOException {
   Properties result = new Properties();

   if (this.localOverride) {
      // Load properties from file upfront, to let local properties override.
      loadProperties(result);
   }

   if (this.localProperties != null) {
      for (Properties localProp : this.localProperties) {
         CollectionUtils.mergePropertiesIntoMap(localProp, result);
      }
   }

   if (!this.localOverride) {
      // Load properties from file afterwards, to let those properties override.
      loadProperties(result);
   }

   return result;
}

/**
 * Load properties into the given instance.
 * @param props the Properties instance to load into
 * @throws IOException in case of I/O errors
 * @see #setLocations
 */
protected void loadProperties(Properties props) throws IOException {
   if (this.locations != null) {
      for (Resource location : this.locations) {
         if (logger.isTraceEnabled()) {
            logger.trace("Loading properties file from " + location);
         }
         try {
            PropertiesLoaderUtils.fillProperties(
                  props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
         }
         catch (FileNotFoundException | UnknownHostException ex) {
            if (this.ignoreResourceNotFound) {
               if (logger.isDebugEnabled()) {
                  logger.debug("Properties resource not found: " + ex.getMessage());
               }
            }
            else {
               throw ex;
            }
         }
      }
   }
}
第二种解析方式

PropertySourcesPlaceholderConfigurer,同上

第三种解析方式

s) {
CollectionUtils.mergePropertiesIntoMap(localProp, result);
}
}

if (!this.localOverride) {
// Load properties from file afterwards, to let those properties override.
loadProperties(result);
}

return result;
}

/**

  • Load properties into the given instance.
  • @param props the Properties instance to load into
  • @throws IOException in case of I/O errors
  • @see #setLocations
    */
    protected void loadProperties(Properties props) throws IOException {
    if (this.locations != null) {
    for (Resource location : this.locations) {
    if (logger.isTraceEnabled()) {
    logger.trace("Loading properties file from " + location);
    }
    try {
    PropertiesLoaderUtils.fillProperties(
    props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
    }
    catch (FileNotFoundException | UnknownHostException ex) {
    if (this.ignoreResourceNotFound) {
    if (logger.isDebugEnabled()) {
    logger.debug("Properties resource not found: " + ex.getMessage());
    }
    }
    else {
    throw ex;
    }
    }
    }
    }
    }

#### 第二种解析方式

PropertySourcesPlaceholderConfigurer,同上

#### 第三种解析方式

通过ConfigurationClassPostProcessor解析@Configuration注解时,解析@PropertySource
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值