Spring IoC 容器从启动到完成 Bean 的创建和注入,涉及一系列精密的步骤。下面结合源码(以 AnnotationConfigApplicationContext 为例)详细拆解整个过程,并说明每个环节的作用。
一、容器启动入口
通常我们使用以下代码启动基于注解的 IoC 容器:
java
ini
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext 的构造方法最终会调用 refresh(),这是 IoC 容器初始化的核心方法,定义在 AbstractApplicationContext 中。
java
scss
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh(); // 关键入口
}
二、refresh() 核心步骤(源码级)
AbstractApplicationContext.refresh() 是整个 IoC 容器启动的模板方法,主要包含以下步骤(以 Spring 5.x 为例):
java
scss
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新上下文
prepareRefresh();
// 2. 获取 BeanFactory(如果已有则刷新,否则创建)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 为 BeanFactory 设置容器级别的功能(类加载器、后处理器等)
prepareBeanFactory(beanFactory);
try {
// 4. 允许子类对 BeanFactory 进行后处理(如添加 BeanPostProcessor)
postProcessBeanFactory(beanFactory);
// 5. 调用 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor(在 Bean 创建前后起作用)
registerBeanPostProcessors(beanFactory);
// 7. 初始化国际化资源等
initMessageSource();
// 8. 初始化事件广播器
initApplicationEventMulticaster();
// 9. 模板方法,供子类初始化特定 Bean(如 Web 容器中的 ServletContext)
onRefresh();
// 10. 注册事件监听器
registerListeners();
// 11. 完成 BeanFactory 初始化,实例化所有非懒加载的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,发布事件
finishRefresh();
} catch (BeansException ex) {
// 异常处理,销毁已创建的 Bean
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
下面分解每个步骤的职责和源码细节。
三、关键步骤详解
1. prepareRefresh()
- 设置启动时间、激活标志、初始化属性源(如系统环境变量、JVM 属性)。
- 校验必要的属性是否存在。
2. obtainFreshBeanFactory()
- 对于
AnnotationConfigApplicationContext,实际上已经在构造时创建了DefaultListableBeanFactory,该方法只是返回它。 - 对于
ClassPathXmlApplicationContext等,会在此处加载 XML 配置并解析为BeanDefinition。
3. prepareBeanFactory(beanFactory)
-
为
BeanFactory添加基础功能:- 设置类加载器、表达式解析器(SpEL)。
- 添加几个特殊的
BeanPostProcessor(如ApplicationContextAwareProcessor)。 - 忽略某些接口的自动装配(如
EnvironmentAware)。 - 注册几个默认的 Bean(如
environment、systemProperties)。
4. postProcessBeanFactory(beanFactory)
- 模板方法,允许子类(如
AnnotationConfigApplicationContext)对BeanFactory进行额外处理。 - 例如,
AnnotationConfigApplicationContext会在此处注册一个ConfigurationClassPostProcessor(属于BeanFactoryPostProcessor),用于处理@Configuration类。
5. invokeBeanFactoryPostProcessors(beanFactory)
- 执行所有已注册的
BeanFactoryPostProcessor。 - 关键后处理器:
ConfigurationClassPostProcessor,它扫描@ComponentScan、解析@Bean等方法,将配置类中的定义转换为BeanDefinition并注册到容器。 - 这一步后,容器拥有了所有 Bean 的
BeanDefinition。
6. registerBeanPostProcessors(beanFactory)
- 注册所有
BeanPostProcessor实例,但不执行它们。这些处理器将在 Bean 实例化前后被调用。 - 顺序:先注册
PriorityOrdered,再Ordered,最后普通。 - 重要内置处理器:
AutowiredAnnotationBeanPostProcessor(处理@Autowired、@Value)、CommonAnnotationBeanPostProcessor(处理@PostConstruct、@PreDestroy)等。
7. initMessageSource()、initApplicationEventMulticaster()、onRefresh()、registerListeners()
- 这些步骤与国际化、事件机制相关,对 Bean 创建流程影响不大,略过。
8. finishBeanFactoryInitialization(beanFactory)
- 最关键的一步:实例化所有非懒加载的单例 Bean。
- 调用
beanFactory.preInstantiateSingletons(),遍历所有BeanDefinition,对单例且非懒加载的 Bean 执行getBean()触发创建。
getBean() 的深入调用链
getBean() → doGetBean() → 检查缓存 → 若未创建,则调用 createBean() → doCreateBean()。
doCreateBean() 的主要步骤(在 AbstractAutowireCapableBeanFactory 中):
java
scss
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 1. 实例化 Bean(通过构造器或工厂方法)
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 2. 处理循环依赖:将 Bean 的早期引用暴露到三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 3. 属性填充(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. 初始化 Bean(执行各种 Aware 接口、BeanPostProcessor、init 方法)
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 5. 注册销毁回调(如 @PreDestroy)
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
核心子步骤源码分析
3.1 createBeanInstance()
-
根据
BeanDefinition选择合适的实例化策略:- 如果定义了工厂方法,使用工厂方法。
- 否则,通过构造器反射创建对象。若有多个构造器,根据参数匹配选择。
3.2 addSingletonFactory()
- 将 Bean 的早期引用(尚未填充属性)放入三级缓存(
singletonFactories),以便解决循环依赖。 - 当其他 Bean 引用当前 Bean 时,可以从三级缓存中获取其早期引用。
3.3 populateBean()
-
执行属性注入:
- 处理
@Autowired、@Resource、@Value等注解(通过AutowiredAnnotationBeanPostProcessor)。 - 处理 XML 配置中的
<property>标签。
- 处理
-
通过
BeanPostProcessor的postProcessAfterInstantiation钩子,允许修改属性注入前状态。
3.4 initializeBean()
-
依次执行:
- 调用
Aware方法(如BeanNameAware、BeanFactoryAware、ApplicationContextAware等)。 - 执行
BeanPostProcessor的postProcessBeforeInitialization(如@PostConstruct在此阶段被调用)。 - 执行自定义
init-method或InitializingBean.afterPropertiesSet()。 - 执行
BeanPostProcessor的postProcessAfterInitialization(AOP 代理在此生成,如AnnotationAwareAspectJAutoProxyCreator)。
- 调用
9. finishRefresh()
- 发布
ContextRefreshedEvent,启动生命周期相关组件。
四、关键源码位置速查
| 步骤 | 关键类 | 关键方法 |
|---|---|---|
| 容器刷新 | AbstractApplicationContext |
refresh() |
| BeanDefinition 注册 | ConfigurationClassPostProcessor |
postProcessBeanDefinitionRegistry() |
| Bean 实例化 | AbstractAutowireCapableBeanFactory |
doCreateBean() |
| 依赖注入 | AbstractAutowireCapableBeanFactory |
populateBean() |
| 循环依赖解决 | DefaultSingletonBeanRegistry |
getSingleton()、三级缓存 |
| 初始化回调 | AbstractAutowireCapableBeanFactory |
initializeBean() |
| AOP 代理生成 | AbstractAutoProxyCreator |
postProcessAfterInitialization() |
五、总结
Spring IoC 容器的启动过程可以概括为:
- 配置加载 :通过
BeanDefinitionReader读取配置,生成BeanDefinition并注册。 - 后处理器调用 :执行
BeanFactoryPostProcessor对BeanDefinition进行修改(如占位符替换、配置类解析)。 - 注册后处理器 :注册
BeanPostProcessor,为 Bean 创建做好准备。 - Bean 创建 :通过
getBean()触发单例 Bean 的实例化,每个 Bean 经历:实例化 → 属性注入 → 初始化 → 生成代理(如果需要)。 - 销毁管理:容器关闭时,销毁单例 Bean。