hexon
发布于 2026-04-26 / 0 阅读
0

14、Spring容器启动过程源码解析

在前面的文章中,我们已经对 Bean 的生命周期核心源码进行了较为详细的分析,但还有两个关键点尚未展开:一个是循环依赖,另一个是 AOP。循环依赖与依赖注入、构造方法注入关系密切,同时也与 AOP 存在关联。从本章开始,我们将逐步分析容器启动的完整过程,而 AOP 和循环依赖的相关内容会放在后续章节进行深入学习。

Bean 的生命周期涉及的内容较为丰富,此前我们已经花费了不少精力进行梳理。不妨先来回顾一下一个 Bean 在创建过程中的核心调用链路:

createBean --> 加载类 --> 实例化前 --> doCreateBean 
--> 推断构造方法、构造方法注入、@Bean 的处理 --> 实例化 --> BeanDefinition 后置处理 
--> 循环依赖处理(尚未分析) 
--> 属性填充(实例化后、依赖注入:自动注入、@Autowired、@Value、@Resource) 
--> Aware 回调 --> 初始化 Bean(初始化前、初始化、初始化后) --> 销毁 Bean

在此之前,我们曾多次提到 refresh 方法,但只涉及其中部分环节。事实上,refresh 方法中还有很多前置步骤,这些步骤主要是为 Bean 的生命周期执行做各项准备和辅助工作。本章我们将重点分析:在容器启动过程中,refresh 方法究竟完成了哪些具体工作。

本文内容:

  1. ApplicationContext创建过程源码解析

  2. ApplicationContext启动过程源码解析

  3. BeanFactory创建过程底层源码解析

  4. BeanFactory预处理过程底层源码解析

  5. requiredProperties的作用和底层源码解析

  6. ApplicationContext重复刷新过程源码解析

  7. Spring容器生命周期LifecycleProcessor底层原理解析

  8. SmartLifecycle的作用和底层原理解析

  9. Spring容器初始化MessageSource底层源码解析

  10. Spring容器初始化事件发布器底层源码解析

启动过程

还是以最简单的入门代码开始:

public class Main {  
    public static void main(String[] args) {  
       // 容器启动过程中会做哪些事情?  
       AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);  
  
       UserService userService = (UserService) applicationContext.getBean("userService", new OrderService());  
       userService.test();  
    }  
}

思考:容器启动过程中会做哪些事情?
至少有扫描和创建非懒加载的单例 Bean这个我们是知道的。
扫描与收集:BeanDefinition、BeanPostProcessor、TypeConvertor、Spel表达式、环境、事件。。。
解析配置类(@Component、@Bean、@Import) --> BeanDefinitionMap --> BeanFactory对象

下面以AnnotationConfigApplicationContext为例子,来介绍容器启动过程中的详细步骤。

  1. 在调用AnnotationConfigApplicationContext的构造方法之前,会调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory,为DefaultListableBeanFactory。同时,再观察父类AbstractAutowireCapableBeanFactory中会去忽略一些依赖接口和初始化instantiationStrategy,其中CglibSubclassingInstantiationStrategy是SimpleInstantiationStrategy的子类,同时具备JDK反射和cglib创建对象的能力。

  2. 构造AnnotatedBeanDefinitionReader,构造过程中会做如下事情:

    1. 创建一个Environment对象

    2. 创建一个ConditionEvaluator用来处理@Condition注解

    3. 设置dependencyComparator:AnnotationAwareOrderComparator,它是一个Comparator,是用来进行排序的,会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序

    4. 设置autowireCandidateResolver:ContextAnnotationAutowireCandidateResolver,用来解析某个Bean能不能进行自动注入,比如某个Bean的autowireCandidate属性是否等于true

    5. 向BeanFactory中添加ConfigurationClassPostProcessor对应的BeanDefinition,它是一个BeanDefinitionRegistryPostProcessor,并且实现了PriorityOrdered接口

    6. 向BeanFactory中添加AutowiredAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessorAdapter,MergedBeanDefinitionPostProcessor

    7. 向BeanFactory中添加CommonAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessor,InitDestroyAnnotationBeanPostProcessor

    8. 向BeanFactory中添加EventListenerMethodProcessor对应的BeanDefinition,它是一个BeanFactoryPostProcessor,SmartInitializingSingleton

    9. 向BeanFactory中添加DefaultEventListenerFactory对应的BeanDefinition,它是一个EventListenerFactory

  3. 构造ClassPathBeanDefinitionScanner,是让ApplicationContext拥有扫描的功能,但@ComponentScan注解使用的并不是这个对象,而是另外new的一个ClassPathBeanDefinitionScanner对象,功能一样,类一样,对象不同而已。

  4. 利用reader注册MyConfig为BeanDefinition,类型为AnnotatedGenericBeanDefinition

  5. 接下来就是调用refresh方法

    EventListenerMethodProcessor和EventListenerFactory我们将在Spring事件监听机制进行学习。

refresh方法中的详细步骤:

  1. prepareRefresh():

    1. 记录启动时间

    2. 可以允许子容器设置一些内容到Environment中,比如Tomcat容器、Servlet的配置

    3. 验证Environment中是否包括了必须要有的属性

  2. obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的refreshBeanFactory方法,具体子类是怎么刷新的得看子类,然后再调用子类的getBeanFactory方法,得到一个BeanFactory(这里主要有两个不同的实现,一个容器refresh方法不能重复执行,一个是可以重复执行,这个机制与后面的SpringMVC等Web环境有关联)

  3. prepareBeanFactory(beanFactory):

    1. 设置beanFactory的类加载器

    2. 设置表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式

    3. 添加PropertyEditorRegistrar:ResourceEditorRegistrar,PropertyEditor类型转化器注册器,用来注册一些默认的PropertyEditor,比如FileEditor,是使用将String转成File对象的

    4. 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationEventPublisherAware等回调方法

    5. 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入(byType/byName/constructor)的时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那么就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于Spring的自动注入autowireMode,@Autowired注解是忽略这个属性的)

      1. EnvironmentAware

      2. EmbeddedValueResolverAware

      3. ResourceLoaderAware

      4. ApplicationEventPublisherAware

      5. MessageSourceAware

      6. ApplicationContextAware

      7. ApplicationStartupAware

      8. 另外其实在构造BeanFactory的时候就已经提前添加了忽略另外三个:

        1. BeanNameAware

        2. BeanFactoryAware

        3. BeanClassLoaderAware

    6. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean

      1. BeanFactory.class:当前BeanFactory对象

      2. ResourceLoader.class:当前ApplicationContext对象

      3. ApplicationEventPublisher.class:当前ApplicationContext对象

      4. ApplicationContext.class:当前ApplicationContext对象

    7. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去

    8. 添加一些单例bean到单例池:

      1. environment:Environment对象

      2. systemProperties:System.getProperties()返回的Map对象

      3. systemEnvironment:System.getenv()返回的Map对象

      4. applicationStartup:JFR相关的

  4. postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩展,具体的子类,可以继续向BeanFactory中再添加一些东西,比如注册RequestScope、SessionScope

  5. invokeBeanFactoryPostProcessors(beanFactory):后面单独分析,核心会解析配置类,从而解析@ComponentScan注解、@Bean注解、@Import注解,从而解析得到BeanDefinition并注册到Spring容器中

  6. registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中程序员可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后)

  7. initMessageSource():如果BeanFactory中存在一个叫做messageSource的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的messageSource属性,让ApplicationContext拥有国际化的功能

  8. initApplicationEventMulticaster():如果BeanFactory中存在一个叫做applicationEventMulticaster的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,让ApplicationContext拥有事件发布的功能

  9. onRefresh():提供给AbstractApplicationContext的子类进行扩展

  10. registerListeners():从BeanFactory中获取ApplicationListener对象并添加到applicationEventMulticaster中去(后面讲事件监听机制的时候详细分析)

  11. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean

    1. 如果BeanFactory中存在一个叫做bootstrapExecutor的BeanDefinition,那么就会把这个Bean对象(一个线程池)创建出来并设置给BeanFactory,从而可以通过线程池并发实例化非懒加载的单例Bean

    2. 如果BeanFactory中存在一个叫做conversionService的BeanDefinition,那么就会把这个Bean对象创建出来并设置给BeanFactory,用来进行类型转换

    3. 设置${}的占位符解析器

    4. 设置BeanFactoryInitializer(Spring6.2新增)

    5. preInstantiateSingletons,真正开始实例化非懒加载的单例Bean

  12. finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了

    1. 设置ApplicationContext的lifecycleProcessor,默认情况下设置的是DefaultLifecycleProcessor

    2. 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命周期扩展机制

    3. 发布ContextRefreshedEvent事件

SmartLifecycle

@Component  
public class MyLifecycle implements SmartLifecycle {  
  
    private boolean isRunning = false;  
  
    // 发布启动事件前会调用start方法(源码中可以看到两者中间没有其他环节)  
    @Override  
    public void start() {  
       System.out.println("start...");  
       isRunning = true;  
    }  
  
    // 发布关闭事件完成才调用stop方法(具体看容器close方法源码)  
    @Override  
    public void stop() {  
       System.out.println("stop...");  
    }  
  
    @Override  
    public boolean isRunning() {  
       return isRunning; // 如果返回false,容器close,stop不会被调用  
    }  
}
public class Main {  
    public static void main(String[] args) {  
       // 容器启动过程中会做哪些事情?  
       AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();  
       applicationContext.register(MyConfig.class);  
       // applicationContext.getEnvironment().setRequiredProperties("kkk");  
  
       AnnotatedGenericBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(UserService.class);  
       beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);  
       applicationContext.registerBeanDefinition("userService", beanDefinition);  
  
       applicationContext.refresh();  
  
       UserService userService = (UserService) applicationContext.getBean("userService", new OrderService());  
       userService.test();  
  
       applicationContext.close();  
    }  
}

总结

本章我们只是大概的把整个容器过程中的方法过了一遍,知道了容器启动过程中在干什么,但其中有些步骤没有展开,比如:解析配置类、事件监听等,后面的文章会展开学习。