Spring Boot 自动装配流程

旧城等待, 2022-08-28 05:46 323阅读 0赞

Spring Boot 自动装配流程-1

  • ImportSelector
    • Import
    • ImportSelector
    • 详解Spring的ImportSelector接口
      • PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(xxx)方法
      • ConfigurationClassPostProcessor
  • Spring Boot Starter自动装配原理 全流程

本章的存在意义是记录本人在学习过程中, 记录自己的疑惑, 梳理知识点, 很多知识点会引用他人的文章,属于二次消化的一个系列

ImportSelector

Import

SpringBoot 的 @Import 用于将指定的类实例注入之Spring IOC Container中。

传送门

ImportSelector

ImportSelector接口是spring中导入外部配置的核心接口

传送门

疑问点

  • ImportSelector是如何被Spring框架调用的呢?

详解Spring的ImportSelector接口

为了解决此疑惑, 特意去复习了一下spring的加载流程, 流程图如下
在这里插入图片描述

根据流程图可知, bean的初始化在 前几步之中, 那么import Select 接口的执行也必然在这之前
在这里插入图片描述

我们以ClassPathXmlApplicationContext为例子,看看Spring在启动过程中是如何调用到ImportSelector接口的。

为了方便阅读, 这里整理了一些注释, 以及顺序整理成了从上到下的这么一个执行顺序

首先执行spring的核心方法 refresh

  1. public void refresh() throws BeansException, IllegalStateException {
  2. synchronized (this.startupShutdownMonitor) {
  3. //刷新前的预处理;
  4. prepareRefresh();
  5. //获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的
  6. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  7. //BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
  8. prepareBeanFactory(beanFactory);
  9. try {
  10. //BeanFactory准备工作完成后进行的后置处理工作
  11. postProcessBeanFactory(beanFactory);
  12. //执行BeanFactoryPostProcessor的方法;
  13. invokeBeanFactoryPostProcessors(beanFactory);
  14. //注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
  15. registerBeanPostProcessors(beanFactory);
  16. //初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
  17. initMessageSource();
  18. //初始化事件派发器
  19. initApplicationEventMulticaster();
  20. //子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
  21. onRefresh();
  22. //注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
  23. registerListeners();
  24. //初始化所有剩下的非懒加载的单例bean
  25. finishBeanFactoryInitialization(beanFactory);
  26. //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
  27. finishRefresh();
  28. }
  29. ......
  30. }

从上面的实现中,我们可以看到该方法做了很多准备、初始化、事件通知等工作。具体的我们就不一一看了,今天我们只关心其中的invokeBeanFactoryPostProcessors方法。

在这里插入图片描述

从上面的代码中我们可以看到,invokeBeanFactoryPostProcessors()方法把具体的调用方法委托给了PostProcessorRegistrationDelegate类。另外,从该方法的名字当中我们也可以看出,该方法主要的目的是:实例化,并调用BeanFactoryPostProcessor类的。BeanFactoryPostProcessor是一个接口,有很多的实现类,这里我们就暂且不管BeanFactoryPostProcessor的具体用处了 (Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点)。我们先进入PostProcessorRegistrationDelegate一窥究竟。

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(xxx)方法

  1. public static void invokeBeanFactoryPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3. // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  4. // 如果有BeanDefinitionRegistryPostProcessors 的话,就先调用它们
  5. // 处理过的Beans
  6. Set<String> processedBeans = new HashSet<String>();
  7. // 是否是BeanDefinitionRegistry类型的BeanFactory. BeanDefinitionRegistry的作用是可以用来注册,删除,获取BeanDefinitions
  8. if (beanFactory instanceof BeanDefinitionRegistry) {
  9. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  10. // 普通类型的BeanFactoryPostProcessor集合
  11. List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
  12. // BeanDefinitionRegistry类型的BeanFactoryPostProcessor集合(BeanDefinitionRegistryPostProcessor继承于BeanFactoryPostProcessor)
  13. List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
  14. new LinkedList<BeanDefinitionRegistryPostProcessor>();
  15. // 对集合beanFactoryPostProcessors进行分类,如果是BeanDefinitionRegistry类型的BeanFactoryPostProcessor;则调用方法 - postProcessBeanDefinitionRegistry()。、、
  16. // postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)该方法的作用是在标准的BeanDefinitions初始化完成后可以修改容器上下文内部的beanDefinition。
  17. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  18. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  19. BeanDefinitionRegistryPostProcessor registryPostProcessor =
  20. (BeanDefinitionRegistryPostProcessor) postProcessor;
  21. registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
  22. registryPostProcessors.add(registryPostProcessor);
  23. }
  24. else {
  25. regularPostProcessors.add(postProcessor);
  26. }
  27. }
  28. // Do not initialize FactoryBeans here: We need to leave all regular beans
  29. // uninitialized to let the bean factory post-processors apply to them!
  30. // Separate between BeanDefinitionRegistryPostProcessors that implement
  31. // PriorityOrdered, Ordered, and the rest.
  32. // 这里不要初始化FactoryBeans,我们需要保留这些普通的beans 不在这里初始化,目的是为了让bean factory post-processor去处理他们。
  33. // 根据BeanDefinitionRegistryPostProcessors 实现的不同接口,拆分开来去调用他们。
  34. String[] postProcessorNames =
  35. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  36. // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
  37. // 首先,调用实现了优先级接口 - PriorityOrdered的BeanDefinitionRegistryPostProcessors
  38. List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
  39. for (String ppName : postProcessorNames) {
  40. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  41. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  42. processedBeans.add(ppName);
  43. }
  44. }
  45. // 排序
  46. sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
  47. // 添加排序好的优先级PostProcessors到registryPostProcessors集合
  48. registryPostProcessors.addAll(priorityOrderedPostProcessors);
  49. // 调用排序好的优先级BeanDefinitionRegistryPostProcessors,postProcessBeanDefinitionRegistry方法会被调用,用来修改,获取,删除容器上下文中的bean定义。
  50. invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
  51. // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
  52. // 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessors ,大致逻辑同上PriorityOrdered的处理
  53. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  54. List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
  55. for (String ppName : postProcessorNames) {
  56. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  57. orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  58. processedBeans.add(ppName);
  59. }
  60. }
  61. sortPostProcessors(beanFactory, orderedPostProcessors);
  62. registryPostProcessors.addAll(orderedPostProcessors);
  63. invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
  64. // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
  65. // 调用所有其它类型的BeanDefinitionRegistryPostProcessors
  66. boolean reiterate = true;
  67. while (reiterate) {
  68. reiterate = false;
  69. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  70. for (String ppName : postProcessorNames) {
  71. if (!processedBeans.contains(ppName)) {
  72. BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
  73. registryPostProcessors.add(pp);
  74. processedBeans.add(ppName);
  75. pp.postProcessBeanDefinitionRegistry(registry);
  76. reiterate = true;
  77. }
  78. }
  79. }
  80. // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
  81. // 调用所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory 方法。
  82. invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
  83. // 调用容器中BeanFactoryPostProcessor类型的bean(不包含BeanDefinitionRegistryPostProcessor类型的beans)。
  84. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  85. }
  86. else {
  87. // Invoke factory processors registered with the context instance.
  88. // 若beanFactory不是BeanDefinitionRegistry类型的,则直接调用容器中所有的BeanFactoryPostProcessor的postProcessBeanFactory 方法。
  89. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  90. }
  91. // 下面是BeanFactoryPostProcessor的具体调用过程,和上面的过程很相似,这里就不多说了。
  92. // Do not initialize FactoryBeans here: We need to leave all regular beans
  93. // uninitialized to let the bean factory post-processors apply to them!
  94. String[] postProcessorNames =
  95. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  96. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  97. // Ordered, and the rest.
  98. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  99. List<String> orderedPostProcessorNames = new ArrayList<String>();
  100. List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  101. for (String ppName : postProcessorNames) {
  102. if (processedBeans.contains(ppName)) {
  103. // skip - already processed in first phase above
  104. }
  105. else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  106. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  107. }
  108. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  109. orderedPostProcessorNames.add(ppName);
  110. }
  111. else {
  112. nonOrderedPostProcessorNames.add(ppName);
  113. }
  114. }
  115. // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
  116. sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
  117. invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  118. // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
  119. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  120. for (String postProcessorName : orderedPostProcessorNames) {
  121. orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  122. }
  123. sortPostProcessors(beanFactory, orderedPostProcessors);
  124. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  125. // Finally, invoke all other BeanFactoryPostProcessors.
  126. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  127. for (String postProcessorName : nonOrderedPostProcessorNames) {
  128. nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  129. }
  130. invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  131. // Clear cached merged bean definitions since the post-processors might have
  132. // modified the original metadata, e.g. replacing placeholders in values...
  133. beanFactory.clearMetadataCache();
  134. }

上面的调用关系中,我们可以看出。在这个方法中有两种类型的PostPorcessor被调用处理了;而这两种PostProcessor的关系如下图:

在这里插入图片描述
BeanDefinitionRegistryPostProcessor继承于BeanFactoryPostProcessor。我们大致看看接口定义的方法:
在这里插入图片描述

postProcessBeanFactory用于在标准的初始化完成后修改容器上下文中的beanFactory。所有bean定义将被加载,但是它们将暂时不被实例化,这允许覆盖,甚至添加一些属性到延迟初始化的bean上。

在这里插入图片描述
postProcessBeanDefinitionRegistry方法在标准化初始化完成后可以修改容器内部的bean definition registry。所有的常规的bean定义都将被加载,但是没有bean被实例化。这允许我们在下一个处理阶段增加一些新的bean定义。

综合上面的逻辑,postProcessBeanDefinitionRegistry是在postProcessBeanFactory方法之前被调用的。

ConfigurationClassPostProcessor

ConfigurationClassPostProcessor类实现了BeanDefinitionRegistryPostProcessor接口,同时还实现了一些其他的接口,如下图:
在这里插入图片描述

我们先来看看postProcessBeanDefinitionRegistry方法的具体内容
在这里插入图片描述

这个方法的主要作用是进一步从配置中获取bean的定义,也就是被@Configuration注解修饰的配置类。该方法中又调用了processConfigBeanDefinitions()方法,该方法主要用于处理@Configuration注解。

在这里插入图片描述
这里忽略一些调用, 最终进入到
在这里插入图片描述
processDeferredImportSelectors方法中调用了processImports方法执行导入,跟进去看看,在processImports 方法中有很重要的一段代码,如下:
在这里插入图片描述

复盘

  1. ImportSelector的导入实现是通过BeanFactoryPostProcessor接口的子接口
  2. BeanDefinitionRegistryPostProcessor来实现的。
  3. ImportSelector接口的处理是伴随着@Configuration注解的处理一起处理的。
  4. ImportSelector接口可以实现自定义条件选择性导入classes。
  5. ImportSelector接口的字接口DeferredImportSelector在所有@Configuration处理完成后才被处理的。
  6. 处理ImportSelector接口时,bean定义已经被加载,但是bean还没有被实例化。
  7. Spring Bootn的自动配置功能就是通过DeferredImportSelector接口的实现类
  8. EnableAutoConfigurationImportSelector做到的。

Spring Boot Starter自动装配原理 全流程

传送门

发表评论

表情:
评论列表 (有 0 条评论,323人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring Boot 自动装配原理

    > 本文已经收录到Github仓库,该仓库包含计算机基础、Java核心知识点、多线程、JVM、常见框架、分布式、微服务、设计模式、架构等核心知识点,欢迎star~ > > G