Spring IoC容器的初始化过程
作者: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 大阶段:
- 容器启动准备:加载配置(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、依赖注入的实现时机。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
