spring ioc(inversion of control,控制反转)容器的初始化是 spring 框架启动的核心过程,它负责创建和管理 bean,以及处理 bean 之间的依赖关系。
以下是 spring ioc 容器初始化的详细流程,结合 源码关键类 和 核心步骤 拆解:
一、核心流程概览
spring ioc 容器初始化分为 2 大阶段:
- 容器启动准备:加载配置(xml/注解),解析成
beandefinition
。 - bean 实例化与依赖注入:根据
beandefinition
创建 bean,处理依赖、初始化。
二、详细步骤(以classpathxmlapplicationcontext为例)
1.容器启动(构造方法调用)
// 示例:创建 xml 应用上下文 applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml");
关键动作:
- 调用父类构造方法,初始化 资源加载器(
resourceloader
)和 ** bean 工厂**(defaultlistablebeanfactory
)。 - 记录配置文件路径(如
applicationcontext.xml
)。
2.加载配置文件(refresh()方法触发)
refresh()
是容器初始化的核心方法,定义在 abstractapplicationcontext
中,包含 13 个关键步骤(简化版流程):
public void refresh() throws beansexception, illegalstateexception { synchronized (this.startupshutdownmonitor) { // 1. 准备刷新:记录启动时间、标记活跃状态、初始化属性源 preparerefresh(); // 2. 创建 bean 工厂(若未创建),并加载 beandefinition configurablelistablebeanfactory beanfactory = obtainfreshbeanfactory(); // 3. 准备 bean 工厂:设置类加载器、后置处理器等 preparebeanfactory(beanfactory); try { // 4. 子类扩展:允许子类修改 bean 工厂(spring boot 常用) postprocessbeanfactory(beanfactory); // 5. 执行 beanfactorypostprocessor:修改 beandefinition(如 propertyplaceholderconfigurer) invokebeanfactorypostprocessors(beanfactory); // 6. 注册 beanpostprocessor:用于 bean 初始化前后增强(如 autowiredannotationbeanpostprocessor) registerbeanpostprocessors(beanfactory); // 7. 初始化 messagesource:国际化支持 initmessagesource(); // 8. 初始化 eventmulticaster:事件广播器 initapplicationeventmulticaster(); // 9. 子类扩展:初始化特殊 bean(如 spring mvc 的 dispatcherservlet) onrefresh(); // 10. 注册事件监听器 registerlisteners(); // 11. 实例化所有非延迟加载的单例 bean finishbeanfactoryinitialization(beanfactory); // 12. 完成刷新:发布 contextrefreshedevent finishrefresh(); } catch (beansexception ex) { // 13. 异常处理:销毁已创建的 bean destroybeans(); cancelrefresh(ex); throw ex; } } }
3.关键步骤拆解
(1)加载beandefinition(步骤 2:obtainfreshbeanfactory)
作用:
- 解析配置文件(xml/注解),生成
beandefinition
(包含 bean 类名、作用域、依赖等信息)。
实现:
- xml 配置:
xmlbeandefinitionreader
解析<bean>
标签,生成beandefinition
。 - 注解配置:
classpathbeandefinitionscanner
扫描@component
、@service
等注解,生成beandefinition
。
示例:
- xml 中的
<bean id="userservice" class="com.example.userservice"/>
会被解析为beandefinition
,记录userservice
的类名、作用域(默认单例)等。
(2)处理beanfactorypostprocessor(步骤 5:invokebeanfactorypostprocessors)
作用:
- 修改
beandefinition
(在 bean 实例化前)。
典型实现:
propertyplaceholderconfigurer
:替换beandefinition
中的占位符(如${jdbc.url}
→ 实际配置值)。configurationclasspostprocessor
:处理@configuration
类,解析@bean
方法。
示例:
- 配置文件中
<bean id="datasource" url="${jdbc.url}"/>
,propertyplaceholderconfigurer
会将${jdbc.url}
替换为application.properties
中的实际值。
(3)注册beanpostprocessor(步骤 6:registerbeanpostprocessors)
作用:
- 注册用于 bean 初始化前后增强的处理器(如
autowiredannotationbeanpostprocessor
处理@autowired
)。
典型实现:
autowiredannotationbeanpostprocessor
:解析@autowired
注解,实现依赖注入。annotationawareaspectjautoproxycreator
:实现 aop 代理,处理@aspect
切面。
(4)实例化单例bean(步骤 11:finishbeanfactoryinitialization)
作用:
- 创建所有非延迟加载的单例 bean(默认
lazy-init="false"
)。
实现:
- 遍历
beandefinition
,调用getbean(beanname)
创建 bean。 - 处理依赖注入(
populatebean
)、初始化(initializebean
)。
关键方法:
// abstractbeanfactory.java protected <t> t dogetbean(string name, @nullable class<t> requiredtype, @nullable object[] args, boolean typecheckonly) throws beansexception { // 1. 检查缓存:单例 bean 先从缓存(singletonobjects)获取 object sharedinstance = getsingleton(beanname); if (sharedinstance != null) { return (t) sharedinstance; } // 2. 创建 bean 实例:调用构造器/工厂方法 beanwrapper instancewrapper = createbeaninstance(beanname, mbd, args); // 3. 依赖注入:填充属性(@autowired、<property>) populatebean(beanname, mbd, instancewrapper); // 4. 初始化:调用 @postconstruct、init-method exposedobject = initializebean(beanname, exposedobject, mbd); // 5. 放入缓存(单例 bean) addsingleton(beanname, exposedobject); return (t) exposedobject; }
(5)发布contextrefreshedevent(步骤 12:finishrefresh)
作用:
- 通知容器已完成初始化,触发
applicationlistener
处理。
示例:
- spring mvc 的
dispatcherservlet
会监听此事件,完成自身初始化(如加载 handlermapping)。
三、核心类与职责
类名 | 职责 |
---|---|
beandefinition | 存储 bean 的元数据(类名、作用域、依赖等) |
beanfactory | 基础 ioc 容器接口,定义 bean 的创建、查找方法 |
applicationcontext | 高级 ioc 容器接口(继承 beanfactory),支持 aop、事件、国际化等 |
abstractapplicationcontext | 实现 applicationcontext 核心逻辑(如 refresh() 方法) |
defaultlistablebeanfactory | 默认 bean 工厂,存储 beandefinition,创建 bean 实例 |
beanpostprocessor | bean 初始化前后增强(如 autowiredannotationbeanpostprocessor) |
beanfactorypostprocessor | bean 实例化前修改 beandefinition(如 propertyplaceholderconfigurer) |
四、总结
spring ioc 容器初始化的核心是 refresh()
方法,通过以下步骤完成:
- 加载配置 → 解析为
beandefinition
; - 处理
beanfactorypostprocessor
→ 修改beandefinition
; - 注册
beanpostprocessor
→ 增强 bean 初始化; - 实例化单例 bean → 处理依赖注入、初始化;
- 发布事件 → 通知容器就绪。
理解这一过程,能清晰掌握 spring 如何管理 bean 的生命周期,以及 aop、依赖注入的实现时机。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论