乐趣区

关于java:Spring源码之容器的功能扩展和refresh方法解析

容器的性能扩大和 refresh 办法解析

在之前文章中咱们理解了对于 Spring 中 bean 的加载流程,并始终应用 BeanFactory 接口以及它的默认实现类 XmlBeanFactory,在 Spring 中还提供了另一个接口 ApplicationContext,用于扩大 BeanFactory 中现有的性能。

首先 BeanFactory 和 ApplicationContext 都是用于加载 bean 的,然而相比之下,ApplicationContext 提供了更多的扩大性能,ApplicationContext 蕴含了 BeanFactory 的所有性能。通常咱们会优先应用 ApplicationContext。

咱们来看看 ApplicationContext 多了哪些性能?

首先看一下写法上的不同。

应用 BeanFactory 形式加载 XML

final BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

应用 ApplicationContext 形式加载 XML

final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");

咱们开始点开 ClassPathXmlApplicationContext 的构造函数,进行剖析。

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
      throws BeansException {super(parent);
   setConfigLocations(configLocations);
   if (refresh) {refresh();
   }
}

在 ClassPathXmlApplicationContext 中能够将配置文件门路以数组的模式传入,对解析及性能实现都在 refresh() 办法中实现。

设置配置门路

public void setConfigLocations(@Nullable String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");
      this.configLocations = new String[locations.length];
      for (int i = 0; i < locations.length; i++) {this.configLocations[i] = resolvePath(locations[i]).trim();}
   }
   else {this.configLocations = null;}
}

此函数次要解析给定的门路数组,如果数组中蕴含特殊符号,如 ${var},那么在 resolvePath 办法中会搜查匹配的零碎变量并替换。

扩大性能

设置完门路后,就能够对文件进行解析和各种性能的实现,能够说在 refresh 办法中简直蕴含了 ApplicationContext 中提供的全副性能,而且此函数的逻辑也非常清晰,能够很容易剖析对应档次和逻辑。

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
      // 筹备刷新的上下文环境, 包含设置启动工夫, 是否激活标识位
      // 初始化属性源 (property source) 配置
      prepareRefresh();

      // 初始化 BeanFactory 并进行 xml 文件读取
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 对 BeanFactory 进行各种性能填充
      prepareBeanFactory(beanFactory);

      try {
         // 子类笼罩办法做额定的解决
         postProcessBeanFactory(beanFactory);

         // 激活各种 BeanFactory 处理器
         invokeBeanFactoryPostProcessors(beanFactory);

         // 注册拦挡 bean 创立的 bean 处理器, 只是注册, 具体调用在 getBean 中
         registerBeanPostProcessors(beanFactory);

         // 为上下文初始化 Message 源, 国际化解决
         initMessageSource();

         // 初始化利用音讯播送器, 并放入 applicationEventMulticaster bean 中
         initApplicationEventMulticaster();

         // 留给子类来初始化其余的 bean
         onRefresh();

         // 在所有注册的 bean 中查找 Listener bean, 注册到音讯播送器中
         registerListeners();

         // 初始化剩下的单例 bean (非惰性)
         finishBeanFactoryInitialization(beanFactory);

         // 实现刷新过程, 告诉生命周期处理器 LifecycleProcessor 刷新过程, 同时收回 ContextRefreshEvent 告诉他人
         finishRefresh();}

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

         // 销毁曾经初始化的 singleton 的 Beans, 免得有些 bean 会始终占用资源
         destroyBeans();

         // 重置流动标记
         cancelRefresh(ex);

         throw ex;
      }

      finally {
         // 重置公共缓存
         resetCommonCaches();}
   }
}

咱们总结一下初始化的步骤。

  1. 初始化前的筹备工作,例如对系统属性或者环境变量进行筹备及验证
  2. 初始化 BeanFactory,并对 XML 文件进行读取。之前咱们说过 ClassPathXmlApplicationContext 中蕴含着 BeanFactory 所提供的所有特色,那么在这一步将会复用 BeanFactory 中的配置文件读取解析及其他性能,在这一步之后 ClassPathXmlApplicationContext 就曾经蕴含了 BeanFactory 所提供的性能,也就是能够对 bean 进行提取等操作
  3. 对 BeanFactory 进行各种性能填充
  4. 子类笼罩办法做额定的解决。次要用于咱们在业务上做进一步扩大
  5. 激活各种 BeanFactory 处理器
  6. 注册拦挡 bean 创立的 bena 处理器,这里仅仅是注册,真正调用在 getBean 中
  7. 为上下文初始化 Message 源,对不同语言的音讯体进行国际化解决
  8. 初始化利用音讯播送器,并放入 ”applicationEventMulticaster” bean 中
  9. 留给子类来初始化其余的 bean
  10. 在所有注册的 bean 中查找 listener bean,注册到音讯播送器中
  11. 初始化剩下的单实例(非惰性)
  12. 实现刷新过程,告诉生命周期处理器 lifecycleProcessor 刷新过程,同时收回 ContextRefreshEvent 来告诉他人

环境筹备

prepareRefresh 办法次要做些筹备工作,比方对系统属性及环境变量的初始化及验证。

  1. initPropertySources

该办法外面是一个空实现,次要用于给咱们依据须要去重写该办法,并在办法中进行个性化的属性解决及设置。

protected void initPropertySources() {// For subclasses: do nothing by default.}
  1. validateRequiredProperties 该办法次要对属性进行验证。默认状况下什么也没校验。在咱们继承了 ClassPathXmlApplicationContext 类重写了 initPropertySources 办法后会进行相干校验。

加载 BeanFactory

obtainFreshBeanFactory 办法次要用来获取 BeanFactory,方才说过 ApplicationContext 领有 BeanFactory 的所有性能,这个办法就是实现 BeanFactory 的中央,也就是说调用完该办法后,applicationContext 就领有了 BeanFactory 的性能。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   // 初始化 BeanFactory, 并进行 XML 文件读取, 将失去的 BeanFactory 记录到以后实体属性中
   refreshBeanFactory();
   // 返回以后实体的 beanFactory 属性
   return getBeanFactory();}
protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();
      closeBeanFactory();}
   try {DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}
   }
   catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for" + getDisplayName(), ex);
   }
}

咱们进入 AbstractRefreshableApplicationContext#refreshBeanFactory() 办法中。

protected final void refreshBeanFactory() throws BeansException {
        // 判断是否存在 beanFactory
        if (hasBeanFactory()) {
            // 销毁所有单例
            destroyBeans();
            // 重置 beanFactory
            closeBeanFactory();}
        try {
            // 创立 beanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 设置序列化 id
            beanFactory.setSerializationId(getId());
            // 定制 beanFactory, 设置相干属性, 包含是否容许笼罩同名称不同定义的对象以及循环依赖
            customizeBeanFactory(beanFactory);
            // 初始化 DocumentReader, 进行 XML 读取和解析
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}
        }
        catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for" + getDisplayName(), ex);
        }
}

总结一下这个办法的流程:

  1. 创立 DefaultListableBeanFactory。申明形式为:BeanFactory bf = new XmlBeanFactory("beanFactoryTest.xml"),其中的 XmlBeanFactory 继承自 DefaultListableBeanFactory,并提供了 XmlBeanDefinitionReader 类型的 reader 属性,也就是说 DefaultListableBeanFactory 是容器的根底,必须首先实例化,这里就是实例化 DefaultListableBeanFactory 的步骤
  2. 指定序列化 ID
  3. 定制 BeanFactory
  4. 加载 BeanDefinition
  5. 应用全局变量记录 BeanFactory 类实例

定制 BeanFactory

首先咱们先理解 customizeBeanFactory 办法,该办法是在根本容器的根底上,减少了是否容许笼罩、是否容许扩大的设置。

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
   // 如果不为空, 设置 beanFactory 对象响应的属性, 含意: 是否容许笼罩同名称的不同定义的对象
   if (this.allowBeanDefinitionOverriding != null) {beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }
   // 如果属性不为空, 设置给 beanFactory 对象相应属性, 含意: 是否容许 bean 之间存在循环依赖
   if (this.allowCircularReferences != null) {beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }
}

具体这里只是做了简略的判断,具体设置属性的中央,应用子类笼罩即可。例如:

/**
 * @author 神秘杰克
 * 公众号: Java 菜鸟程序员
 * @date 2022/6/12
 * @Description 自定义 ClassPathXmlApplicationContext
 */
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {

   @Override
   protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {super.setAllowBeanDefinitionOverriding(false);
      super.setAllowCircularReferences(false);
      super.customizeBeanFactory(beanFactory);
   }
}

加载 BeanDefinition

在初始化了 DefaultListableBeanFactory 后,咱们还须要 XmlBeanDefinitionReader 来读取 XML 文件,这个步骤中首先要做的就是初始化 XmlBeanDefinitionReader。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // 为指定 beanFactory 创立 XmlBeanDefinitionReader
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // 进行环境变量的设置
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // 对 beanDefinitionReader 进行设置, 能够笼罩
   initBeanDefinitionReader(beanDefinitionReader);
   loadBeanDefinitions(beanDefinitionReader);
}

初始化了 DefaultListableBeanFactory 和 XmlBeanDefinitionReader 后,咱们就能够进行配置文件的读取了。最终 XmlBeanDefinitionReader 所去读的 BeanDefinitionHolder 都会注册到 DefaultListableBeanFactory 中。

通过该办法后类型为 DefaultListableBeanFactory 中的变量 beanFactory 曾经蕴含了所有解析好的配置。对于配置文件的读取这一部分之前文章曾经讲过,这里就不再赘述。

性能扩大

咱们在实现了配置文件解析后,咱们接着进入 prepareBeanFactory 办法。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // 设置 beanFactory 的 ClassLoader 为以后 context 的 ClassLoader
   beanFactory.setBeanClassLoader(getClassLoader());
   // 设置 beanFactory 的表达式语言解决
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   // 为 beanFactory 减少了一个默认的 propertyEditor, 次要是对 bean 的属性等设置治理的一个工具
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // 增加 BeanPostProcessor
   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.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // 减少了 ApplicationListenerDetector 次要是检测 bean 是否实现了 ApplicationListener 接口
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 减少对 AspectJ 的反对
   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()));
   }

   // 增加默认的零碎环境 bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

该办法次要做了几个方面的扩大:

  • 减少了对 SpEL 语言的反对
  • 减少了对属性编辑器的反对
  • 减少了一些内置类,比方 EnvironmentAware、MessageSourceAware 的信息注入
  • 设置了依赖性能可疏忽的接口
  • 注册了一些固定依赖的属性
  • 减少 AspectJ 的反对
  • 将相干环境变量及属性注册以单例模式注册

BeanFactory 的后处理

BeanFactory 作为 Spring 中容器的根底,用于寄存所有曾经加载的 bean,为了保障程序的高扩展性,Spring 针对 BeanFactory 做了大量的扩大,比方 PostProcessor 等都是在这里实现的。

激活注册的 BeanFactoryPostProcessor

在学习之前,咱们先理解一下 BeanFactoryPostProcessor 的用法。BeanFactoryPostProcessor 接口和 BeanPostProcessor 相似,能够对 bean 的定义进行解决。也就是说,Spring IOC 容器容许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取配置元数据,并能够批改它。BeanFactoryPostProcessor 能够配置多个,通过实现 Ordered 接口设置“order”来管制执行程序。

须要留神的是如果在容器中定义一个 BeanFactoryPostProcessor,它仅仅对此容器中的 bean 进行后置解决。BeanFactoryPostProcessor 不会对其余容器中的 bean 进行后置解决。

1.BeanFactoryPostProcessor 的典型利用:PropertySourcesPlaceholderConfigurer

首先咱们来看一下配置文件:

<bean id="hello" class="cn.jack.Hello">
   <property name="msg">
      <value>${bean.msg}</value>
   </property>
</bean>

在外面咱们应用到了变量援用:${bean.msg},这就是 Spring 的扩散配置,咱们能够在配置文件中配置该属性的值。

application.properties

bean.msg=hi

而后咱们再进行配置文件的配置。

<bean id="helloHandler" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>application.properties</value>
            </list>
        </property>
    </bean>

这时候就明确了,咱们通过 PreferencesPlaceholderConfigurer 中进行获取咱们的配置信息。咱们查看该类能够晓得间接性继承了 BeanFactoryPostProcessor 接口。

当 Spring 加载任何实现了这个接口的 bean 时,都会在 bean 工厂加载所有 bena 的配置之后执行 postProcessBeanFactory 办法。在办法中先后调用了 mergeProperties、convertProperties、processProperties 这三个办法,别离失去配置、将失去的配置进行转换为适合的类型、最初将配置内容告知 BeanFactory。

正是通过实现 BeanFactoryPostProcessor,BeanFactory 会在实例化任何 bean 之前取得配置信息,从而可能正确解析 bean 配置文件中的变量援用

PropertySourcesPlaceholderConfigurer 曾经取代了 PropertyPlaceholderConfigurer,因为汇聚了 Environment、多个 PropertySource。所以它可能管制取值优先级、程序,并且还提供了拜访的办法,前期再想获取也不是问题。

2. 应用自定义 BeanFactoryPostProcessor

咱们本人实现一个自定义 BeanFactoryPostProcessor,去除咱们不想要显示的属性值的性能来展现自定义 BeanFactoryPostProcessor 的创立及应用,例如 bean 定义中咱们屏蔽掉‘guapi’、‘shazi’。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="cn.jack.ObscenityRemovingBeanFactoryPostProcessor" id="customBeanFactoryPostProcessor">
        <property name="obscenities">
            <set>
                <value>guapi</value>
                <value>shazi</value>
            </set>
        </property>
    </bean>

    <bean class="cn.jack.SimpleBean" id="simpleBean">
        <property name="userName" value="jack"/>
        <property name="address" value="guapi"/>
        <property name="email" value="shazi"/>
    </bean>

</beans>
public class SimpleBean {

   private String userName;
   private String email;
   private String address;
        //getter  setter
}
public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

   private final Set<String> obscenities;

   public ObscenityRemovingBeanFactoryPostProcessor() {this.obscenities = new HashSet<>();
   }

   /**
    * 将所有 bean 的参数中含有 obscenities 汇合中的值进行屏蔽
    */
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {String[] beanNames = beanFactory.getBeanDefinitionNames();
      for (String beanName : beanNames) {final BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
         StringValueResolver valueResolver = strVal -> {if (isObscene(strVal)){return  "*****";}
            return strVal;
         };
         final BeanDefinitionVisitor beanDefinitionVisitor = new BeanDefinitionVisitor(valueResolver);
         beanDefinitionVisitor.visitBeanDefinition(beanDefinition);
      }
   }

   public boolean isObscene(Object value){String potentialObscenity = value.toString().toUpperCase();
      return this.obscenities.contains(potentialObscenity);
   }

   public void setObscenities(Set<String> obscenities){this.obscenities.clear();
      for (String obscenity : obscenities) {this.obscenities.add(obscenity.toUpperCase());
      }
   }

}

启动类:

public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("beanFactory.xml");
      SimpleBean simpleBean = (SimpleBean) ac.getBean("simpleBean");
      System.out.println(simpleBean);
   }
}

输入后果:

SimpleBean{userName='jack', email='*****', address='*****'}

咱们通过 ObscenityRemovingBeanFactoryPostProcessor 咱们很好的屏蔽掉了咱们不想要显示的属性。

激活 BeanFactoryPostProcessor

咱们在理解了 BeanFactoryPostProcessor 的用法之后就能够持续回到咱们的 refresh 办法中持续钻研源码了。

进入 invokeBeanFactoryPostProcessors 办法中。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {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()));
   }
}

咱们持续进入具体重载办法中 invokeBeanFactoryPostProcessors。

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

   // 将曾经执行过的 BeanFactoryPostProcessor 存储在 processedBeans,避免反复执行
   Set<String> processedBeans = new HashSet<>();
   // 对 BeanDefinitionRegistry 类型进行解决
   if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      // 用来寄存 BeanFactoryPostProcessor 对象
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      // 用来寄存 BeanDefinitionRegistryPostProcessor 对象
      // 不便对立执行实现了 BeanDefinitionRegistryPostProcessor 接口父类的办法
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
      // 解决内部定义的 BeanFactoryPostProcessor, 将 BeanDefinitionRegistryPostProcessor 与 BeanFactoryPostProcessor 辨别开
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            // 对于 BeanDefinitionRegistryPostProcessor 类型, 须要先调用此办法, 再增加到汇合中
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         } else {
            // 记录惯例 BeanFactoryPostProcessor
            regularPostProcessors.add(postProcessor);
         }
      }

      // 寄存以后须要执行的 BeanDefinitionRegistryPostProcessor
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // 调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor。// 获取所有实现了 BeanDefinitionRegistryPostProcessor 接口的类名
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         // 判断以后类是否实现了 PriorityOrdered 接口
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 将 BeanDefinitionRegistryPostProcessor 类型存入 currentRegistryProcessors 中
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            // 提前寄存到 processedBeans,防止反复执行,然而此处还未执行
            processedBeans.add(ppName);
         }
      }
      // 对 currentRegistryProcessors 汇合中的 BeanDefinitionRegistryPostProcessor 类型进行排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      // 增加到 registryProcessors 汇合,用于后续执行父接口的 postProcessBeanFactory 办法
      registryProcessors.addAll(currentRegistryProcessors);
      // 遍历汇合,执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()办法
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      // 执行结束后清空该汇合
      currentRegistryProcessors.clear();

      // 接着, 调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors
      // 这里再次获取 BeanDefinitionRegistryPostProcessor, 是因为有可能在下面办法执行过程中增加了 BeanDefinitionRegistryPostProcessor
      // 而上面解决 BeanFactoryPostProcessor 的时候又不须要反复获取了是为什么呢?// 因为增加 BeanFactoryPostProcessor 与 BeanDefinitionRegistryPostProcessor 只能在 BeanDefinitionRegistryPostProcessor 中增加,在 BeanFactoryPostProcessor 是无奈增加的
      for (String ppName : postProcessorNames) {
         // 判断以后 bean 没有被执行过,并且实现了 Ordered 接口
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 如果 BeanFactory 中没有该 Bean 则会去创立该 Bean
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // 最初解决没有实现 Ordered 与 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         // 再次获取 BeanDefinitionRegistryPostProcessor
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {
               // 将本次要执行的 BeanDefinitionRegistryPostProcessor 寄存到 currentRegistryProcessors
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();}

      // 当初,调用到目前为止解决的所有处理器的 postProcessBeanFactory 回调。invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   } else {
      // BeanFactory 如果不归属于 BeanDefinitionRegistry 类型, 则间接执行 beanFactoryPostProcessor
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

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

   // 用于寄存实现了 priorityOrdered 接口的 BeanFactoryPostProcessor
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 用于寄存实现了 ordered 接口的 BeanFactoryPostProcessor 名称
   List<String> orderedPostProcessorNames = new ArrayList<>();
   // 用于寄存无排序的 BeanFactoryPostProcessor 名称
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      // 如果曾经执行过了,则不做解决
      if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}
      // 如果实现了 PriorityOrdered 则增加
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      // 如果实现了 Ordered 则增加
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);
      }
      // 如果没有排序则增加到指定汇合
      else {nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // 首先调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // 而后调用实现 Ordered 的 BeanFactoryPostProcessors。List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // 最初调用其余没有排序的 BeanFactoryPostProcessor。List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // 清空缓存
   beanFactory.clearMetadataCache();}

注册 BeanPostProcessor

理解了 BeanFactoryPostProcessors 的调用后,咱们当初来理解下 BeanPostProcessor,这里 仅仅是注册,并不是调用。真正的调用在 bean 实例化阶段进行的。

在 BeanFactory 中并没有实现后处理器的主动注册性能,所以在调用的时候如果没有进行被动注册则是不可能应用的。然而在 ApplicationContext 中增加了被动注册性能。

比方自定义这样的后处理器:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

   @Override
   public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {System.out.println("===");
      return null;
   }
}
<bean class="cn.jack.MyInstantiationAwareBeanPostProcessor"/>

在应用 ApplicationContext 形式获取 bean 的时候会在获取之前打印出“===”,在 BeanFactory 形式进行 bean 的加载是不会有该打印的。

这个个性就是在 registerBeanPostProcessors 中实现的。

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
   // 获取所有实现 BeanPostProcessor 接口的类
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // 注册一个 BeanPostProcessorChecker,用来记录 bean 在 BeanPostProcessor 实例化时的信息
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // 辨别实现不同接口的 BeanPostProcessors
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   // 依据不同类型进行 add
   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);
      }
   }

   // 排序后执行注册实现了 PriorityOrdered 的 BeanPostProcessors
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // 注册实现 Ordered 接口的 BeanPostProcessors
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      // 拿到 ppName 对应的 BeanPostProcessor 实例对象
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      // 将 ppName 对应的 BeanPostProcessor 实例对象增加到 orderedPostProcessors, 筹备执行注册
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         // 如果 ppName 对应的 bean 实例也实现了 MergedBeanDefinitionPostProcessor 接口, 则增加到该汇合中
         internalPostProcessors.add(pp);
      }
   }
   // 对 orderedPostProcessors 进行排序并注册
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // 注册所有惯例的 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);

   // 注册所有 mergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor, 并非反复注册
   // 在 beanFactory.addBeanPostProcessor 中会先移除曾经存在的 BeanPostProcessor
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // 增加 ApplicationListener 探测器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

初始化音讯资源

在 initMessageSource 中次要性能是提取配置文件中的 messageSource,并将其记录在 Spring 容器中,也就是 ApplicationContext 中。如果用户未设置资源文件的话,则获取 Spring 默认的配置 delegatingMessageSource。

protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   // Bean 的名称必须要是 messageSource
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { //MESSAGE_SOURCE_BEAN_NAME = messageSource
      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 + "]");
      }
   }
   else {
      // 如果用户并没有定义配置文件, 那么应用长期的 DelegatingMessageSource 以便于作为调用 getMessage 的返回
      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 + "]");
      }
   }
}

这里规定资源文件必须为 messageSource,否则就会获取不到自定义资源配置。

初始化 ApplicationEventMulticaster

initApplicationEventMulticaster 办法实现比较简单,存在两种状况:

  • 如果用户自定义了事件播送器,那么就是用用户自定义的事件播送器
  • 如果用户没有自定义事件播送器,那么应用默认的 ApplicationEventMulticaster
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   // 判断容器中是否存在 BeanDefinitionName 为 applicationEventMulticaster 的 bd, 也就是自定义的事件监听多路播送器,必须实现 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 + "]");
      }
   }
   else {
      // 如果没有,则默认采纳 SimpleApplicationEventMulticaster
      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() + "]");
      }
   }
}

最初,作为播送器,肯定是用于寄存监听器并在适合的时候调用监听器,咱们进入默认的播送器实现类 SimpleApplicationEventMulticaster 中看一下。

看到如下办法:

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);
      }
   }
}

能够推断,当产生 Spring 事件的时候会默认应用 SimpleApplicationEventMulticaster 的 multicastEvent 来播送事件,遍历所有监听器,并应用监听器中的 onApplicationEvent 办法来进行监听器的解决。而对于每个监听器来说其实都能够获取到产生的事件,然而是否进行解决则由事件监听器决定。

注册监听器

咱们重复提到了监听器,咱们接下来看一下 Spring 注册监听器的时候又做了哪些逻辑操作?

protected void registerListeners() {
   // 首先注册动态的指定的监听器, 注册的是非凡的事件监听器, 而不是配置中的 bean
   for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // 这里不会初始化 FactoryBean, 咱们须要保留所有的一般 bean
   // 不会实例化这些 bean, 让后置处理器能够感知到它们
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // 当初有了事件播送组, 公布之前的利用事件
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

只是将一些非凡的监听器注册到播送组中,那些在 bean 配置文件中实现了 ApplicationListener 接口的类还没有实例化,所以此时只是将 name 保留到了播送组中,将这些监听器注册到播送组中的操作时在 bean 的后置处理器中实现的,那时候 bean 的实例化曾经实现了。

初始化非提早加载单例

实现 BeanFactory 的初始化工作,其中包含 ConversionService 的设置、配置解冻以及非提早加载的 bean 的初始化工作。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 初始化此上下文的转换服务
   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));
   }

   // 如果 beanFactory 之前没有注册解析器,则注册默认的解析器, 例如 ${}解析成真正的属性:次要用于注解属性值的解析
   if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // 解决 @EnableLoadTimeWeaving 或  <context:load-time-weaver/> 标记的类
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);
   }

   // 长期类加载器设置为空
   beanFactory.setTempClassLoader(null);

   // 解冻所有的 bean 定义, 阐明注册的 bean 定义将不被批改或者进一步解决
   beanFactory.freezeConfiguration();

   // 初始化剩下的单例实例(非惰性)
   beanFactory.preInstantiateSingletons();}

首先,咱们先理解下 ConversionService 类所提供的作用。

1.ConversionService 的设置

之前咱们提到能够用自定义类型转换器把 String 类型转换为 Date,在 Spring 中也提供了应用 Converter 来进行转换。

2. 解冻配置

解冻所有的 bean 定义,阐明注册的 bean 定义将不被批改或者进行任何一步的解决。

public void freezeConfiguration() {
   this.configurationFrozen = true;
   this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

3. 初始化提早加载

ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化。提前实例化也就意味着作为初始化过程的一部分,ApplicationContext 实例会创立并配置所有单例 bean,这个实例化过程就是在 finishBeanFactoryInitialization 办法中的 preInstantiateSingletons 办法中实现的。

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in" + this);
   }

   // 创立 beanDefinitionNames 的正本 beanNames 用于后续的遍历,以容许 init 等办法注册新的 bean 定义
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // 遍历 beanNames, 触发所有非懒加载单例 bean 的初始化
   for (String beanName : beanNames) {
      // 获取 beanName 对应的 MergedBeanDefinition
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //bd 对应的不是抽象类 && 并且是单例 && 并且不是懒加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 判断是否为 FactoryBean
         if (isFactoryBean(beanName)) {
            // 通过前缀 & 和 beanName 拿到 Bean
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            // 如果为 FactoryBean
            if (bean instanceof FactoryBean) {final FactoryBean<?> factory = (FactoryBean<?>) bean;
               // 判断这个 FactoryBean 是否心愿急迫的初始化
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               // 如果心愿急迫的初始化,则通过 beanName 获取 bean 实例
               if (isEagerInit) {getBean(beanName);
               }
            }
         }
         else {
            // 如果 beanName 对应的 bean 不是 FactoryBean,只是一般 Bean,通过 beanName 获取 bean 实例
            getBean(beanName);
         }
      }
   }

   // 遍历 beanNames,触发所有 SmartInitializingSingleton 的后初始化回调
   for (String beanName : beanNames) {
      // 拿到 beanName 对应的 bean 实例
      Object singletonInstance = getSingleton(beanName);
      // 判断 singletonInstance 是否实现了 SmartInitializingSingleton 接口
      if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         // 触发 SmartInitializingSingleton 实现类的 afterSingletonsInstantiated 办法
         if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

finishRefresh

在 Spring 中提供了 Lifecycle 接口,该接口蕴含 start/stop 办法,实现此接口后 Spring 会保障在启动时候调用其 start 办法开始申明周期,并在 Spring 敞开时候调用 stop 办法来完结申明周期。通常用来配置后台程序,在启动后始终运行(比方 MQ)而 ApplicationContext 最初一步 finishRefresh 办法就是实现这一性能。

protected void finishRefresh() {
   // 革除资源缓存
   clearResourceCaches();

   //1. 为此上下文初始化生命周期处理器
   initLifecycleProcessor();

   //2. 首先将刷新结束事件流传到生命周期处理器(触发 isAutoStartup 办法返回 true 的 SmartLifecycle 的 start 办法)
   getLifecycleProcessor().onRefresh();

   //3. 推送上下文刷新结束事件到相应的监听器
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}

1.initLifecycleProcessor

当 ApplicationContext 启动或进行时,它会通过 LifecycleProcessor 来和所有申明的 bean 的周期做状态更新,而在 LifecycleProcessor 的应用前首先进行初始化。

protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   // 判断 BeanFactory 是否曾经存在生命周期处理器(beanName=lifecycleProcessor)if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
      this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
      if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
      }
   }
   else {
      // 如果不存在,则应用 DefaultLifecycleProcessor
      DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
      defaultProcessor.setBeanFactory(beanFactory);
      this.lifecycleProcessor = defaultProcessor;
      // 并将 DefaultLifecycleProcessor 作为默认的生命周期处理器,注册到 BeanFactory 中
      beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
      if (logger.isTraceEnabled()) {
         logger.trace("No'" + LIFECYCLE_PROCESSOR_BEAN_NAME + "'bean, using" +
               "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
      }
   }
}

2.onRefresh

启动所有实现了 Lifecycle 接口的 bean

public void onRefresh() {startBeans(true);
   this.running = true;
}
private void startBeans(boolean autoStartupOnly) {Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
   Map<Integer, LifecycleGroup> phases = new HashMap<>();
   lifecycleBeans.forEach((beanName, bean) -> {if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);
         LifecycleGroup group = phases.get(phase);
         if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
            phases.put(phase, group);
         }
         group.add(beanName, bean);
      }
   });
   if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<>(phases.keySet());
      Collections.sort(keys);
      for (Integer key : keys) {phases.get(key).start();}
   }
}

3.publishEvent

当实现 ApplicationContext 初始化的时候,要通过 Spring 中的公布机制来收回 ContextRefreshedEvent 事件,以保障对应的监听器能够做进一步的逻辑解决。

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");

   // 如有必要,将事件装璜为 ApplicationEvent
   ApplicationEvent applicationEvent;
   if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;
   }
   else {applicationEvent = new PayloadApplicationEvent<>(this, event);
      if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}
   }

   // Multicast right now if possible - or lazily once the multicaster is initialized
   if (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);
   }
   else {
      // 应用事件播送器播送事件到相应的监听器
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
   }

   // 通过 parent 公布事件
   if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
      }
      else {this.parent.publishEvent(event);
      }
   }
}

到这里,refresh 办法就解析实现了。下一步就是 AOP 了。

退出移动版