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、依赖注入的实现时机。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
 
             我要评论
我要评论 
                                             
                                             
                                            
发表评论