spring-IoC容器启动流程源码分析

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!


以下是Spring IoC容器启动流程的源码分析,以AnnotationConfigApplicationContext为例,详细说明其核心步骤和关键源码实现:

1. 容器初始化入口

创建AnnotationConfigApplicationContext

java 复制代码
// 用户代码:初始化容器
AnnotationConfigApplicationContext context = 
    new AnnotationConfigApplicationContext(AppConfig.class);

构造函数源码分析

java 复制代码
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();  // 1. 调用无参构造函数初始化核心组件
    register(componentClasses); // 2. 注册配置类
    refresh(); // 3. 核心方法:刷新容器(初始化所有Bean)
}

2. 核心流程:AbstractApplicationContext.refresh()

refresh()方法是容器初始化的核心,定义了完整的启动流程:

java 复制代码
// AbstractApplicationContext.java
public void refresh() {
    // 步骤1:准备BeanFactory和上下文环境
    prepareRefresh();

    // 步骤2:创建并配置BeanFactory(核心容器)
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // 步骤3:配置BeanFactory(注册内置BeanPostProcessor等)
    prepareBeanFactory(beanFactory);

    try {
        // 步骤4:调用BeanFactoryPostProcessor(修改Bean定义)
        postProcessBeanFactory(beanFactory);
        invokeBeanFactoryPostProcessors(beanFactory);

        // 步骤5:注册BeanPostProcessor(干预Bean初始化)
        registerBeanPostProcessors(beanFactory);

        // 步骤6:初始化消息源、事件广播器等
        initMessageSource();
        initApplicationEventMulticaster();

        // 步骤7:初始化其他特殊Bean(如Tomcat嵌入式容器)
        onRefresh();

        // 步骤8:注册监听器
        registerListeners();

        // 步骤9:实例化所有非懒加载的单例Bean
        finishBeanFactoryInitialization(beanFactory);

        // 步骤10:完成刷新,发布事件
        finishRefresh();
    } catch (...) {
        // 异常处理
    }
}

3. 关键源码步骤详解

(1) 创建BeanFactory:obtainFreshBeanFactory()

java 复制代码
// AbstractApplicationContext.obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory(); // 由子类实现
    return getBeanFactory();
}

// GenericApplicationContext.refreshBeanFactory()
protected final void refreshBeanFactory() {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    this.beanFactory = new DefaultListableBeanFactory(); // 创建默认Bean工厂
    customizeBeanFactory(this.beanFactory); // 定制BeanFactory(如是否允许循环依赖)
}

(2) 加载Bean定义:invokeBeanFactoryPostProcessors()

java 复制代码
// PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
public static void invokeBeanFactoryPostProcessors(...) {
    // 1. 调用BeanDefinitionRegistryPostProcessor(如ConfigurationClassPostProcessor)
    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            ((BeanDefinitionRegistryPostProcessor) postProcessor).postProcessBeanDefinitionRegistry(registry);
        }
    }

    // 2. 处理@ComponentScan、@Import等注解
    // ConfigurationClassPostProcessor解析@Configuration类
    // 生成BeanDefinition并注册到BeanFactory
}

(3) 注册BeanPostProcessor:registerBeanPostProcessors()

java 复制代码
// PostProcessorRegistrationDelegate.registerBeanPostProcessors()
public static void registerBeanPostProcessors(...) {
    // 1. 获取所有BeanPostProcessor的Bean定义
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // 2. 实例化并注册(按优先级排序)
    for (String ppName : postProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        beanFactory.addBeanPostProcessor(pp); // 添加到BeanFactory的BeanPostProcessor列表
    }
}

(4) 实例化单例Bean:finishBeanFactoryInitialization()

java 复制代码
// DefaultListableBeanFactory.preInstantiateSingletons()
public void preInstantiateSingletons() {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 触发Bean的创建
            getBean(beanName); 
        }
    }
}

// AbstractBeanFactory.getBean() → doGetBean()
protected <T> T doGetBean(...) {
    // 1. 检查单例缓存
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null) {
        return (T) sharedInstance;
    }

    // 2. 创建Bean实例
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            return createBean(beanName, mbd, args); // 实际创建Bean
        });
        return (T) sharedInstance;
    }
}

// AbstractAutowireCapableBeanFactory.createBean()
protected Object createBean(...) {
    // 1. 实例化(反射调用构造函数)
    Object beanInstance = doCreateBean(beanName, mbd, args);

    // 2. 属性填充(依赖注入)
    populateBean(beanName, mbd, instanceWrapper);

    // 3. 初始化(调用init方法、BeanPostProcessor)
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    return exposedObject;
}

4. 核心类与设计模式

类/接口 作用 设计模式
DefaultListableBeanFactory Bean定义注册、依赖解析、单例缓存的核心实现 工厂模式、单例模式
BeanDefinition 描述Bean的元数据(类名、作用域、属性等) 元数据模式
BeanPostProcessor 在Bean初始化前后插入逻辑(如@Autowired处理) 责任链模式
BeanFactoryPostProcessor 在Bean定义注册后、实例化前修改配置(如占位符替换) 观察者模式
SingletonBeanRegistry 管理单例Bean的三级缓存(解决循环依赖) 缓存机制

5. 三级缓存解决循环依赖

java 复制代码
// DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry ... {
    // 一级缓存:完整Bean
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    // 二级缓存:早期暴露对象(未完成属性注入)
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
    // 三级缓存:ObjectFactory(用于生成代理对象)
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 依次从一级→二级→三级缓存查找
    }
}

6. 调试建议

  1. 断点位置

    • AnnotationConfigApplicationContext.refresh()方法入口
    • ConfigurationClassPostProcessor.processConfigBeanDefinitions()(解析@Configuration
    • AutowiredAnnotationBeanPostProcessor.postProcessProperties()(处理@Autowired
    • AbstractAutowireCapableBeanFactory.createBean()(Bean实例化)
  2. 日志配置

    properties 复制代码
    logging.level.org.springframework.beans=DEBUG
    logging.level.org.springframework.context=DEBUG

总结

Spring IoC容器的启动流程是一个多阶段协作的过程,核心步骤包括:

  1. BeanFactory初始化 → 2. Bean定义加载 → 3. 扩展处理器执行 → 4. 单例Bean实例化
    通过源码分析可以深入理解Spring如何实现依赖注入、解决循环依赖,以及如何通过扩展点(如BeanPostProcessor)定制容器行为。
相关推荐
跟着珅聪学java30 分钟前
spring boot +Elment UI 上传文件教程
java·spring boot·后端·ui·elementui·vue
我命由我1234535 分钟前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
lilye6636 分钟前
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析
java·服务器·前端
徐小黑ACG2 小时前
GO语言 使用protobuf
开发语言·后端·golang·protobuf
战族狼魂4 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
xyliiiiiL5 小时前
ZGC初步了解
java·jvm·算法
杉之6 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
hycccccch6 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
bobz9657 小时前
k8s 怎么提供虚拟机更好
后端
bobz9657 小时前
nova compute 如何创建 ovs 端口
后端