AnnotationConfigApplicationContext 启动流程
一、入口:构造器调用
AnnotationConfigApplicationContext
java
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this(); // 步骤1:无参构造
register(componentClasses); // 步骤2:注册配置类
refresh(); // 步骤3:刷新容器(核心)
}
二、this() ------ 初始化基础组件
AnnotationConfigApplicationContext调用父类 GenericApplicationContext 的无参构造,并初始化两个核心组件:
java
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this); // 注解读取器
this.scanner = new ClassPathBeanDefinitionScanner(this); // 类路径扫描器
}
在父类 GenericApplicationContext中,会创建内部 DefaultListableBeanFactory :
js
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
关键点: AnnotatedBeanDefinitionReader 构造时会通过 AnnotationConfigUtils 注册一批基础后处理器(如 ConfigurationClassPostProcessor 、 AutowiredAnnotationBeanPostProcessor 等)到 BeanFactory。
三、register(componentClasses) ------ 注册 BeanDefinition
AnnotationConfigApplicationContext 委托给 reader :
js
public void register(Class<?>... componentClasses) {
this.reader.register(componentClasses); // 解析 @Configuration/@Component 注册为 BeanDefinition
}
此时只是把 Config.class 注册为一个 BeanDefinition, 尚未实例化 。
四、refresh() ------ 核心容器刷新(模板方法)
真正干活的是 AbstractApplicationContext ,流程如下:
js
public void refresh() {
startupShutdownLock.lock(); // 加锁,防止并发启动/关闭
prepareRefresh(); // 1. 准备刷新:设置启动时间、active 标志
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2. 获取内部 BeanFactory
prepareBeanFactory(beanFactory); // 3. 准备 BeanFactory:注册 ApplicationContextAwareProcessor 等
postProcessBeanFactory(beanFactory); // 4. 子类扩展点(GenericApplicationContext 为空实现)
invokeBeanFactoryPostProcessors(beanFactory); // 5. 执行 BeanFactoryPostProcessor(核心!)
registerBeanPostProcessors(beanFactory); // 6. 注册 BeanPostProcessor
initMessageSource(); // 7. 初始化消息源(国际化)
initApplicationEventMulticaster(); // 8. 初始化事件广播器
onRefresh(); // 9. 子类扩展点(初始化特殊 bean)
registerListeners(); // 10. 注册 ApplicationListener
finishBeanFactoryInitialization(beanFactory); // 11. 实例化所有非懒加载单例(核心!)
finishRefresh(); // 12. 发布 ContextRefreshedEvent
}
几个关键步骤详解
步骤 2: obtainFreshBeanFactory() 触发 GenericApplicationContext.java#L289-L295 的 refreshBeanFactory() ,仅校验 refreshed 原子标志(只能刷新一次):
js
protected final void refreshBeanFactory() {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException("...just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
步骤 5: invokeBeanFactoryPostProcessors(beanFactory) 这是注解配置的核心: ConfigurationClassPostProcessor 会解析 @Configuration 类、 @ComponentScan 、 @Bean 方法、 @Import 等,把所有相关类补充注册为 BeanDefinition。
步骤 11: finishBeanFactoryInitialization(beanFactory) 触发所有非懒加载单例的实例化与依赖注入(包括构造器注入、 @Autowired 、 InitializingBean 、 init-method 等)。此时 serviceImpl 、 AopDemoDao 等 bean 才真正被创建。
步骤 12: finishRefresh() 发布 ContextRefreshedEvent ,触发所有监听器。
五、流程时序总结
scss
new AnnotationConfigApplicationContext(Config.class)
│
├─ this() // 父类 GenericApplicationContext 创
建 beanFactory
│ └─ new AnnotatedBeanDefinitionReader(this) // 注册基础后处理器
│ └─ new ClassPathBeanDefinitionScanner(this)
│
├─ register(Config.class) // 注册 Config 为 BeanDefinition
│ └─ reader.register(...)
│
└─ refresh() // 容器真正启动
├─ prepareRefresh() // 设 active=true
├─ obtainFreshBeanFactory() // 校验只刷新一次
├─ prepareBeanFactory() // 注册 Aware 处理器
├─ invokeBeanFactoryPostProcessors() // ConfigurationClassPostProcessor
解析 @Configuration
├─ registerBeanPostProcessors() // 注册 BeanPostProcessor(AOP 代理在
此介入)
├─ initMessageSource() / initApplicationEventMulticaster()
├─ onRefresh() // 子类扩展
├─ registerListeners()
├─ finishBeanFactoryInitialization() // ★ 实例化所有单例 bean
└─ finishRefresh() // 发布 ContextRefreshedEvent
类继承结构
BeanFactory
└─ HierarchicalBeanFactory
└─ ListableBeanFactory
└─ ConfigurableBeanFactory
└─ AbstractRefreshableBeanFactory / DefaultListableBeanFactory
└─ GenericApplicationContext ←
AnnotationConfigApplicationContext 的父类
└─ AnnotationConfigApplicationContext
AnnotationConfigApplicationContext 继承 GenericApplicationContext (持有 DefaultListableBeanFactory ),并实现 AnnotationConfigRegistry (提供 register / scan 能力)。所以它是 注解驱动 + 不可重复刷新 的轻量上下文。