1. 项目概述
Spring框架的IoC容器启动过程一直是Java开发者需要深入理解的核心机制。refresh()方法作为整个启动流程的入口,短短一行代码背后隐藏着Spring框架最精妙的设计思想。本文将带你深入refresh()方法的执行链路,逐层剖析Spring容器初始化的完整过程。
2. 核心设计解析
2.1 refresh()方法的作用域
refresh()方法定义在AbstractApplicationContext类中,作为模板方法提供了容器初始化的标准流程。这个方法的设计体现了Spring框架的两个重要原则:
- 模板方法模式:定义了初始化的固定步骤,但允许子类在特定步骤进行扩展
- 好莱坞原则:容器控制组件的初始化流程,组件只需等待被调用
2.2 初始化流程的12个关键步骤
refresh()方法内部包含了12个核心操作步骤,每个步骤都承担着特定的职责:
- prepareRefresh():初始化前的准备工作
- obtainFreshBeanFactory():创建或获取BeanFactory实例
- prepareBeanFactory():配置标准BeanFactory
- postProcessBeanFactory():允许子类对BeanFactory进行后置处理
- invokeBeanFactoryPostProcessors():执行BeanFactory后置处理器
- registerBeanPostProcessors():注册Bean后置处理器
- initMessageSource():初始化国际化资源
- initApplicationEventMulticaster():初始化事件广播器
- onRefresh():模板方法,子类可以扩展
- registerListeners():注册监听器
- finishBeanFactoryInitialization():完成BeanFactory初始化
- finishRefresh():发布容器刷新事件
3. 关键步骤深度解析
3.1 BeanFactory的创建与配置
obtainFreshBeanFactory()方法负责创建或获取BeanFactory实例。在默认实现中:
- 如果是第一次刷新,会创建新的DefaultListableBeanFactory
- 如果已经存在BeanFactory,则会销毁原有实例并创建新的
- 同时会加载Bean定义(loadBeanDefinitions)
prepareBeanFactory()方法会对新创建的BeanFactory进行标准配置:
// 设置类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置EL表达式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); // 添加属性编辑器注册器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar());3.2 后置处理器的执行顺序
invokeBeanFactoryPostProcessors()方法的执行逻辑特别值得关注:
- 先执行实现了PriorityOrdered接口的后置处理器
- 然后执行实现了Ordered接口的后置处理器
- 最后执行普通的后置处理器
- 对于每种类型,都会先执行BeanDefinitionRegistryPostProcessor
这种顺序设计确保了关键的后置处理器能够优先执行,比如ConfigurationClassPostProcessor就是通过PriorityOrdered接口确保自己最先执行。
4. Bean初始化过程
4.1 finishBeanFactoryInitialization详解
这个方法触发了所有非懒加载单例Bean的初始化,核心逻辑在DefaultListableBeanFactory的preInstantiateSingletons()方法中:
- 遍历所有Bean定义
- 对非抽象、单例、非懒加载的Bean执行getBean()
- getBean()会触发Bean的完整生命周期:
- 实例化
- 属性填充
- 初始化前处理
- 初始化
- 初始化后处理
4.2 循环依赖的解决方案
Spring通过三级缓存巧妙地解决了循环依赖问题:
- 一级缓存:存放完全初始化好的Bean
- 二级缓存:存放原始Bean对象(尚未填充属性)
- 三级缓存:存放Bean工厂对象
当检测到循环依赖时,Spring会提前暴露正在创建的Bean的引用,通过ObjectFactory的方式实现。
5. 事件发布机制
5.1 事件广播器的初始化
initApplicationEventMulticaster()方法负责初始化事件广播器:
- 如果容器中存在名为"applicationEventMulticaster"的Bean,则直接使用
- 否则创建SimpleApplicationEventMulticaster实例
- 广播器默认使用同步方式发布事件
5.2 监听器的注册过程
registerListeners()方法执行以下操作:
- 添加静态指定的监听器
- 从BeanFactory中获取实现了ApplicationListener接口的Bean
- 发布早期应用事件(如果有)
6. 性能优化与最佳实践
6.1 容器启动性能优化
- 合理使用懒加载:对不立即需要的Bean设置为懒加载
- 优化Bean定义:减少不必要的Bean定义
- 合理使用Bean后置处理器:避免在postProcessBeanFactory中执行耗时操作
6.2 常见问题排查
- Bean创建失败:检查依赖注入是否正确
- 循环依赖:合理设计Bean之间的依赖关系
- 后置处理器不生效:检查是否实现了正确的接口和顺序
7. 扩展点与自定义实现
Spring提供了多个扩展点允许开发者自定义容器行为:
- BeanFactoryPostProcessor:修改Bean定义
- BeanPostProcessor:干预Bean创建过程
- ApplicationContextInitializer:在刷新前执行自定义逻辑
- ApplicationListener:监听容器事件
理解refresh()方法的完整执行链路,不仅可以帮助我们更好地使用Spring框架,还能在需要时进行深度定制和优化。