乐于分享
好东西不私藏

Spring IoC 容器完整生命周期源码拆解

Spring IoC 容器完整生命周期源码拆解
一、从上帝视角俯瞰:什么是IoC容器?

在深入源码之前,必须先澄清一个常见的误解:IoC容器不是那个单例池Map。很多人认为容器就是个ConcurrentHashMap,把Bean创建出来往里面一放就完事了——这种理解过于简化。

准确地说,IoC容器是一组组件和协作流程的集合,包括BeanFactory、单例池(singletonObjects)、BeanPostProcessor、BeanDefinitionRegistry等,以及它们之间的复杂交互。容器管理Bean的完整生命周期,而不仅仅是存储Bean。

核心接口体系

BeanFactory(顶级容器接口) ↑ApplicationContext(高级容器接口,继承BeanFactory) ↑├── ClassPathXmlApplicationContext(XML配置启动)├── FileSystemXmlApplicationContext(文件系统路径启动)└── AnnotationConfigApplicationContext(纯注解模式启动)

BeanFactory定义了容器的基础规范,ApplicationContext在此基础上增加了国际化、事件传播、资源访问等能力。


二、容器启动的“总指挥”:refresh()方法

所有IoC容器的启动,无论XML还是注解方式,最终都会汇聚到AbstractApplicationContext.refresh()方法。这是整个容器初始化的入口和总控。

@Overridepublic void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1. 刷新前的预处理 prepareRefresh(); // 2. 获取并刷新BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3. BeanFactory预准备工作 prepareBeanFactory(beanFactory); try { // 4. 空方法,留给子类扩展 postProcessBeanFactory(beanFactory); // 5. 调用BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactory); // 6. 注册BeanPostProcessor registerBeanPostProcessors(beanFactory); // 7. 初始化消息源 initMessageSource(); // 8. 初始化事件广播器 initApplicationEventMulticaster(); // 9. 空方法,子类扩展 onRefresh(); // 10. 注册事件监听器 registerListeners(); // 11. 初始化所有非懒加载单例Bean finishBeanFactoryInitialization(beanFactory); // 12. 完成刷新,发布事件 finishRefresh(); } catch (BeansException ex) { // 异常处理:销毁已创建的Bean destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } }}

下面逐一拆解每个步骤的核心逻辑。


三、refresh() 12步源码深度拆解

第1步:prepareRefresh() — 刷新前的预热

这一步做的是“准备工作”性质的初始化:

protected void prepareRefresh() { // 设置启动时间 this.startupDate = System.currentTimeMillis(); // 设置容器状态:活跃中,未关闭 this.closed.set(false); this.active.set(true); // 初始化属性源(空实现,留给子类扩展) initPropertySources(); // 校验必要属性是否存在 getEnvironment().validateRequiredProperties(); // 准备早期事件监听器集合 if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } // 准备早期事件集合 this.earlyApplicationEvents = new LinkedHashSet<>();}

关键扩展点:子类可以重写initPropertySources()来添加自定义配置来源(如从网络、数据库加载配置),或通过setRequiredProperties()指定必须存在的属性键,缺失会导致启动失败。


第2步:obtainFreshBeanFactory() — 获取/创建BeanFactory

这一步的核心是获取一个“干净”的BeanFactory实例:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 刷新BeanFactory:如果已有则销毁,重新创建 refreshBeanFactory(); return getBeanFactory();}

对于ClassPathXmlApplicationContext,这里会:

    本质:这一步完成了Bean定义的加载和注册,但Bean实例还未创建。


    第3步:prepareBeanFactory() — BeanFactory的“装修”

    刚创建好的BeanFactory是个“毛坯房”,需要添置一些基础设施:

    protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置表达式解析器(支持#{...}) beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); // 添加属性编辑器注册器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar()); // 添加BeanPostProcessor:ApplicationContextAwareProcessor // 负责处理各种Aware接口的回调 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略以下接口的自动装配 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); // ...等 // 注册一些特殊的依赖 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.classthis); beanFactory.registerResolvableDependency(ApplicationContext.classthis); // 注册一个空的单例Bean用于占位 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}

    这一步让BeanFactory具备了处理Aware回调、表达式解析等能力。


    第4步:postProcessBeanFactory() — 子类扩展点

    这是一个空方法,留给子类在BeanFactory准备完成后、BeanPostProcessor注册之前进行定制扩展。例如AnnotationConfigWebApplicationContext会在这里注册一些Web相关的组件。


    第5步:invokeBeanFactoryPostProcessors() — 执行BeanFactory后置处理器

    这是容器启动中第一个重量级阶段:调用所有BeanFactoryPostProcessor。

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 委托给专门的代理类处理 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());}

    BeanFactoryPostProcessor的作用:在所有Bean实例化之前,修改BeanDefinition元数据。例如修改作用域、添加属性、甚至新增或删除Bean定义。

    执行顺序:

      特别注意:BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它允许直接操作BeanDefinitionRegistry(增删改Bean定义),执行优先级更高。


      第6步:registerBeanPostProcessors() — 注册Bean后置处理器

      这一步从容器中找出所有BeanPostProcessor类型的Bean,将它们注册到BeanFactory的beanPostProcessors列表中。

      publicstaticvoidregisterBeanPostProcessors( ConfigurableListableBeanFactory beanFactory,  AbstractApplicationContext applicationContext) { // 找出所有BeanPostProcessor类型的Bean名称 String[] postProcessorNames = beanFactory.getBeanNamesForType( BeanPostProcessor.classtruefalse); // 按优先级分类 List priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 先实例化优先级最高的 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 按优先级顺序注册 sortAndRegister(priorityOrderedPostProcessors, beanFactory); // 注册Ordered的 sortAndRegister(orderedPostProcessors, beanFactory); // 注册普通的 sortAndRegister(nonOrderedPostProcessors, beanFactory); // 最后注册一个特殊的:ApplicationListenerDetector // 负责检测并注册ApplicationListener beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

      关键区分:BeanFactoryPostProcessor操作Bean定义(元数据层面),BeanPostProcessor操作Bean实例(对象层面),两者执行时机完全不同。


      第7步:initMessageSource() — 初始化国际化消息源

      查找容器中是否有名为messageSource的Bean,如果有则使用;否则创建一个空的DelegatingMessageSource作为默认实现,保证getMessage()方法调用不会报错。


      第8步:initApplicationEventMulticaster() — 初始化事件广播器

      查找容器中是否有名为applicationEventMulticaster的Bean,如果有则使用;否则创建一个SimpleApplicationEventMulticaster作为默认实现。这个广播器负责将容器事件分发给所有注册的监听器。


      第9步:onRefresh() — 子类扩展点(Web容器特有)

      又是一个空方法,留给子类扩展。在Web环境中,GenericWebApplicationContext会在此处创建Web相关的资源。


      第10步:registerListeners() — 注册事件监听器

      将容器中所有实现了ApplicationListener接口的Bean注册到事件广播器。同时,如果之前有早期事件(在广播器初始化之前产生的事件),现在会被广播出去。


      第11步:finishBeanFactoryInitialization() — 实例化所有非懒加载单例Bean

      这是容器启动中最核心、最重量级的步骤。完成所有准备工作后,Spring终于开始创建Bean实例了。

      protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 1. 初始化类型转换服务 beanFactory.setConversionService(...); // 2. 注册默认的嵌入值解析器 beanFactory.setEmbeddedValueResolver(...); // 3. 提前初始化LoadTimeWeaverAware(AOP相关) beanFactory.getBean(LOAD_TIME_WEAVER_BEAN_NAME); // 4. 冻结所有BeanDefinition:后续不再允许修改 beanFactory.freezeConfiguration(); // 5. 实例化所有非懒加载单例Bean beanFactory.preInstantiateSingletons();}

      preInstantiateSingletons()方法会遍历所有BeanDefinition,对于非抽象、非懒加载、单例的Bean,逐个调用getBean()触发实例化。

      Bean的完整创建流程(在getBean() → doGetBean() → createBean() → doCreateBean()中完成):

      实例化(调用构造函数) ↓暴露早期引用到三级缓存(解决循环依赖) ↓属性填充(populateBean)- 依赖注入 ↓Aware接口回调 ↓BeanPostProcessor.postProcessBeforeInitialization ↓执行初始化方法(@PostConstruct / afterPropertiesSet / init-method ↓BeanPostProcessor.postProcessAfterInitialization ↓注册到一级缓存(单例池)

      循环依赖的解决机制:Spring通过三级缓存来解决单例Bean的循环依赖:

      public class DefaultSingletonBeanRegistry { // 一级缓存:完全初始化好的单例Bean private final Map singletonObjects = new ConcurrentHashMap<>(256); // 二级缓存:早期暴露的Bean引用(尚未填充属性) private final Map earlySingletonObjects = new HashMap<>(16); // 三级缓存:ObjectFactory,用于生成早期引用(可代理) private final Map> singletonFactories = new HashMap<>(16);}

      当A依赖B、B依赖A时:


        第12步:finishRefresh() — 完成刷新,发布事件

        最后一步,容器启动完毕:

        protectedvoidfinishRefresh() { // 1. 清理资源缓存 initLifecycleProcessor(); getLifecycleProcessor().onRefresh(); // 2. 发布ContextRefreshedEvent事件 publishEvent(new ContextRefreshedEvent(this)); // 3. 注册MBean(JMX相关) registerLiveBeans();}

        此时容器已完全就绪,可以对外提供服务了。


        四、完整流程速查表


        五、写在最后:理解源码的核心价值

        理解Spring IoC容器源码,最重要的不是记住每一行代码,而是把握设计思想和扩展点

          掌握了这套流程,当遇到Bean初始化顺序异常、循环依赖报错、扩展点执行不符合预期等问题时,你就不再是盲目搜索,而是可以精准定位到源码的某个环节进行分析。