欢迎光临
我们一直在努力

《解读spring源码》IOC容器模块

        在 Spring 框架的庞大体系中,IOC(Inversion of Control,控制反转)容器无疑是最核心的基石。它不仅实现了对象的集中管理与解耦,更通过高度抽象和扩展机制,支撑了 AOP、事务管理、Spring Boot 自动配置等高级功能。

        本文将基于 Spring Framework 5.3.x 版本,从源码角度深入剖析 IOC 容器的实现原理。

IOC容器启动全流程分析

以AnnotationConfigApplicationContext为例:

package com.gyz;

import com.gyz.config.AppConfig;
import com.gyz.bean.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCContainerDemo {
public static void main(String[] args) {
System.out.println("开始启动IOC容器…");

// 1. 创建AnnotationConfigApplicationContext实例
// 这个过程会触发容器的初始化
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);

System.out.println("IOC容器启动完成!");

// 2. 从容器获取Bean
UserService userService = context.getBean(UserService.class);
System.out.println("获取到UserService bean: " + userService.getName());

// 3. 使用Bean
userService.sayHello();

System.out.println("关闭IOC容器…");
// 4. 关闭容器,触发销毁方法
((AnnotationConfigApplicationContext) context).close();
System.out.println("IOC容器已关闭!");
}
}

public AnnotationConfigApplicationContext(Class<?>… componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}

创建ApplicationContext容器示例,调用refresh()来启动容器:

​
//准备刷新上下文
prepareRefresh();

//获取BeanFactory,加载BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//配置BeanFactory
prepareBeanFactory(beanFactory);

try {
//子类扩展点
postProcessBeanFactory(beanFactory);

StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//执行BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessors
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();

//初始化消息源
initMessageSource();

//初始化事件广播器
initApplicationEventMulticaster();

//springboot在这里启动内嵌tomcat
onRefresh();

//注册监听器
registerListeners();

//实例化所有非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);

//最后一步:发布容器刷新完成事件
finishRefresh();
}

​

阶段一:准备刷新 (prepareRefresh)

  • 核心逻辑:
    • 设置容器的启动时间戳(startupDate)。
    • 将容器的 active 状态设为 true,标记为活跃状态。
    • 初始化 Environment(环境变量),校验必要的属性(如 @Value 注入的配置项是否存在)。
    • 初始化早期的事件监听器集合(earlyApplicationEvents),用于暂存容器完全启动前发布的事件。

阶段二:获取 BeanFactory (obtainFreshBeanFactory)

  • 核心逻辑:
    • 这一步会调用 refreshBeanFactory()。
    • 如果之前存在旧的 BeanFactory,则先销毁其中的单例 Bean 并关闭旧工厂。
    • 创建一个新的 DefaultListableBeanFactory(Spring 的核心工厂实现)。
    • 加载 BeanDefinition:通过 BeanDefinitionReader 解析配置类(@Configuration)、XML 或注解(@ComponentScan),将 Bean 的定义信息(Class、Scope、Lazy等)注册到工厂的 beanDefinitionMap 中。

阶段三:配置 BeanFactory (prepareBeanFactory)

  • 核心逻辑:对刚创建的工厂进行基础“装修”:
    • 设置类加载器(ClassLoader)。
    • 设置表达式解析器(SpEL)。
    • 注册一些特殊的 BeanPostProcessor,例如 ApplicationContextAwareProcessor,它负责处理 @Autowired 注入 ApplicationContext 本身的情况。
    • 注册可解析的依赖(例如,当 Bean 需要 BeanFactory 类型时,直接注入当前工厂)。

阶段四:子类扩展与后置处理器 (postProcessBeanFactory & invokeBeanFactoryPostProcessors)

  • postProcessBeanFactory:这是一个空的模板方法。Web 环境下的子类(如 AnnotationConfigServletWebServerApplicationContext)会重写它,用于添加特定的配置(如注册 ServletContext 相关的处理器)。
  • invokeBeanFactoryPostProcessors:极其关键。它会执行 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor。
    • 核心处理器 ConfigurationClassPostProcessor 在这里运行,它会解析 @Import、@Bean 等注解,完善 BeanDefinition。
    • 这一步决定了最终容器里到底有哪些 Bean。

阶段五:注册 Bean 后置处理器 (registerBeanPostProcessors)

  • 核心逻辑:从容器中找出所有实现了 BeanPostProcessor 接口的 Bean(如 AutowiredAnnotationBeanPostProcessor 处理 @Autowired,CommonAnnotationBeanPostProcessor 处理 @PostConstruct)。
  • 注意:这里只是注册到处理器链中,并不执行。它们会在后续 Bean 实例化时被调用。

阶段六:初始化基础设施组件

  • initMessageSource:初始化消息源,用于支持多语言(i18n)。如果用户没有定义名为 messageSource 的 Bean,Spring 会使用一个空的默认实现。
  • initApplicationEventMulticaster:初始化事件广播器。如果用户没有定义名为 applicationEventMulticaster 的 Bean,Spring 会创建一个 SimpleApplicationEventMulticaster(默认同步执行事件,也可配置线程池异步执行)。

阶段七:子类特定初始化 (onRefresh)

  • 核心逻辑:又一个模板方法。
  • 典型应用:在 Spring Boot 中,ServletWebServerApplicationContext 重写了此方法,在这里启动内嵌的 Tomcat/Jetty 服务器。

阶段八:注册监听器与实例化单例

  • registerListeners:将实现了 ApplicationListener 接口的 Bean 注册到事件广播器中。
  • finishBeanFactoryInitialization:最耗时的步骤。触发所有非懒加载的单例 Bean 的实例化。
    • 遍历所有 BeanDefinition,调用 getBean()。
    • 执行构造函数、属性注入(populateBean)、调用 BeanPostProcessor、执行初始化方法(InitializingBean)。
    • 这会触发完整的 Bean 生命周期:实例化 -> 属性填充(依赖注入) -> 初始化(@PostConstruct, InitializingBean) -> 放入单例池。

阶段九:完成刷新 (finishRefresh)

  • 核心逻辑:
    • 清空某些缓存。
    • 初始化 LifecycleProcessor 并启动实现了 Lifecycle 接口的 Bean。
    • 发布 ContextRefreshedEvent 事件:通知所有监听器,容器已刷新完成。这是很多后置操作(如定时任务启动)的触发点。
    • 如果有内嵌服务器,注册关闭钩子(Shutdown Hook)
赞(0)
未经允许不得转载:171主机测评 » 《解读spring源码》IOC容器模块
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址