Spring IoC容器的初始化过程

 更新时间:2025年08月18日 11:56:42   作者:dj_master  
Spring IoC容器初始化分两阶段:加载配置生成BeanDefinition,处理PostProcessor修改定义,注册PostProcessor增强初始化,实例化单例Bean并注入依赖,核心类包含BeanDefinition、BeanFactory、ApplicationContext,refresh()方法主导整个流程,实现依赖注入和AOP

Spring IoC(Inversion of Control,控制反转)容器的初始化是 Spring 框架启动的核心过程,它负责创建和管理 Bean,以及处理 Bean 之间的依赖关系。

以下是 Spring IoC 容器初始化的详细流程,结合 源码关键类核心步骤 拆解:

一、核心流程概览

Spring IoC 容器初始化分为 2 大阶段

  1. 容器启动准备:加载配置(XML/注解),解析成 BeanDefinition
  2. 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 实例
BeanPostProcessorBean 初始化前后增强(如 AutowiredAnnotationBeanPostProcessor)
BeanFactoryPostProcessorBean 实例化前修改 BeanDefinition(如 PropertyPlaceholderConfigurer)

四、总结

Spring IoC 容器初始化的核心是 refresh() 方法,通过以下步骤完成:

  1. 加载配置 → 解析为 BeanDefinition
  2. 处理 BeanFactoryPostProcessor → 修改 BeanDefinition
  3. 注册 BeanPostProcessor → 增强 Bean 初始化;
  4. 实例化单例 Bean → 处理依赖注入、初始化;
  5. 发布事件 → 通知容器就绪。

理解这一过程,能清晰掌握 Spring 如何管理 Bean 的生命周期,以及 AOP、依赖注入的实现时机。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java日常练习题,每天进步一点点(32)

    Java日常练习题,每天进步一点点(32)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • 详解Java中Iterable与Iterator用法

    详解Java中Iterable与Iterator用法

    在本文中小编给大家分享了关于Java中Iterable与Iterator的用法知识点内容,有兴趣的朋友们可以学习下。
    2018-10-10
  • SpringBoot使用Apache Tika检测敏感信息

    SpringBoot使用Apache Tika检测敏感信息

    Apache Tika 是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Apache Tika检测敏感信息从而实现数据泄露防护吧
    2025-01-01
  • Java 实战项目之疫情防控管理系统详解

    Java 实战项目之疫情防控管理系统详解

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Java实现一个疫情防控管理系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • Spring Cloud Gateway 服务网关快速实现解析

    Spring Cloud Gateway 服务网关快速实现解析

    这篇文章主要介绍了Spring Cloud Gateway 服务网关快速实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 浅谈java String不可变的好处

    浅谈java String不可变的好处

    这篇文章主要介绍了java String不可变的好处,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Java StampedLock实现原理与最佳实践记录

    Java StampedLock实现原理与最佳实践记录

    本文介绍了Java 8引入的StampedLock,这是一种多模式同步控制组件,通过“戳”(stamp)标识锁的状态,支持写锁、悲观读锁和乐观读三种模式,StampedLock在特定场景下能够大幅提升系统性能,特别是在读多写少的场景中,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • java导出生成csv文件的方法

    java导出生成csv文件的方法

    这篇文章主要为大家详细介绍了java导出生成csv文件的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • Spring中allowedOriginPatterns和allowedOrigins方法有何不同详解

    Spring中allowedOriginPatterns和allowedOrigins方法有何不同详解

    这篇文章主要给大家介绍了关于Spring中allowedOriginPatterns和allowedOrigins方法有何不同,allowedOriginPatterns和allowedOrigins都是用来设置允许跨域请求的来源,需要的朋友可以参考下
    2023-10-10
  • Idea工具中创建 SpringBoot工程及入门详解

    Idea工具中创建 SpringBoot工程及入门详解

    这篇文章主要介绍了Idea工具中创建 SpringBoot工程及入门分析详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02

最新评论