- AnnotationConfigApplicationContext 是 Spring 中基于注解配置的应用上下文实现,其初始化流程严格遵循 Java 类加载机制(父类优先)和 Spring 容器的分层设计。以下从用户触发创建到容器完全就绪,分阶段详细解析。
- 解析源码目的:熟悉Spring基于注解启动流程,扩展Spring开发使用。
- 源码位置:
org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
一、时序图
二、类继承关系
1. AnnotationConfigApplicationContext

三、源码解析
步骤1:触发容器创建
- 目标:创建一个基于注解配置的 Spring 应用上下文实例,传入的AppConfig.class(通常是带@Configuration注解的类)将作为容器的配置源。
- 调用构造函数
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
步骤2:构造函数调用链(父类优先初始化)
- 根据 Java 类加载机制,子类构造必须先调用父类构造函数(隐式调用super())。因此,AnnotationConfigApplicationContext(以下简称 AAC)的构造流程会先完成父类链的初始化。
1. 父类 AbstractApplicationContext 初始化
- 调用链:AAC 的父类链为:AAC → GenericApplicationContext → AbstractApplicationContext。
- AbstractApplicationContext 构造
- resourcePatternResolver:默认使用PathMatchingResourcePatternResolver,用于解析类路径资源(如classpath*: *.xml)。
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
2. 父类 GenericApplicationContext 初始化
- GenericApplicationContext 是AbstractApplicationContext的子类,负责管理BeanFactory(Spring 的核心 Bean 容器)。
- 创建 DefaultListableBeanFactory
- 通过new DefaultListableBeanFactory()创建 Spring 的默认 Bean 工厂实例(blfInstance),并赋值给GenericApplicationContext的beanFactory字段。
- DefaultListableBeanFactory 是 Spring 的核心 Bean 工厂实现,负责存储BeanDefinition(Bean 的元数据)、实例化 Bean、处理依赖注入等。
- DefaultListableBeanFactory初始化源码详解
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
3. 子类 AnnotationConfigApplicationContext 构造逻辑
- 在完成父类初始化后,AAC 开始执行自身的构造逻辑。
- 初始化注解解析器 AnnotatedBeanDefinitionReader。
- 通过new AnnotatedBeanDefinitionReader(this)创建实例
- 解析带注解的类(如@Configuration、@Component、@Service),将其转换为BeanDefinition(Spring 内部对 Bean 的元数据描述)。
- 自动注册 Spring 内置的注解处理器(如AutowiredAnnotationBeanPostProcessor,用于处理@Autowired依赖注入)。
- AnnotatedBeanDefinitionReader初始化源码详解
this.reader = new AnnotatedBeanDefinitionReader(this);
- 初始化类路径扫描器 ClassPathBeanDefinitionScanner。
this.scanner = new ClassPathBeanDefinitionScanner(this);
步骤3:注册提供的配置类
- 在构造函数的最后一步,AAC 会调用register(ComponentClasses…)方法,将用户传入的配置类(如AppConfig.class)注册到容器中。
- 具体逻辑
- AnnotatedBeanDefinitionReader 的register()方法会将配置类解析为BeanDefinition,并存储到DefaultListableBeanFactory的beanDefinitionMap中。
- BeanDefinition 包含类名(beanClass)、作用域(scope,默认单例)、初始化方法(initMethod)、依赖关系(dependencies)等元数据。
- Spring BeanDefinition:Bean 的构建蓝图
context.register(AppConfig.class);
步骤4:容器刷新(核心初始化流程)
- 由于容器刷新内容很多,需要注意的小细节也很多,后续单独解析源码。
四、流程图
AnnotationConfigApplicationContext 初始化
├── 1. 用户触发创建容器
│ └── User → AAC: new AnnotationConfigApplicationContext(ComponentClasses...)
├── 2. AAC 构造函数启动
│ └── AAC: 构造方法 (Class<?>... componentClasses)
│ ├── 2.1 父类构造链初始化(Java 规范:先父类后子类)
│ │ ├── 2.1.1 GAC 父类构造
│ │ │ └── AAC → GAC: 调用父类 GenericApplicationContext () 构造
│ │ │ ├── 2.1.1.1 AACParent 父类构造
│ │ │ │ └── GAC → AACParent: 调用父类 AbstractApplicationContext () 构造
│ │ │ │ └── AACParent: 初始化 resourcePatternResolver(PathMatchingResourcePatternResolver)
│ │ │ ├── 2.1.1.2 GAC 初始化 BeanFactory
│ │ │ │ ├── GAC → BLF: new DefaultListableBeanFactory()
│ │ │ │ │ └── BLF → GAC: 返回 BeanFactory 实例(blfInstance)
│ │ │ │ └── GAC: this.beanFactory = blfInstance
│ │ └── 2.1.2 父类构造完成(GAC、AACParent 初始化完毕)
│ ├── 2.2 子类 AAC 初始化注解处理组件
│ │ ├── 2.2.1 初始化 AnnotatedBeanDefinitionReader
│ │ │ └── AAC → Reader: new AnnotatedBeanDefinitionReader(this)
│ │ │ └── Reader → AAC: 返回实例(用于解析注解类为 BeanDefinition)
│ │ └── 2.2.2 初始化 ClassPathBeanDefinitionScanner
│ │ └── AAC → Scanner: new ClassPathBeanDefinitionScanner(this)
│ │ └── Scanner → AAC: 返回实例(用于扫描类路径组件)
│ ├── 2.3 注册用户传入的组件类
│ │ └── AAC: register(componentClasses)
│ │ └── AAC → Reader: reader.register(componentClasses)
│ │ └── Reader → BLF: 向 blfInstance 注册 BeanDefinition(存储组件类元数据)
│ └── 2.4 容器刷新(核心初始化)
│ └── AAC: refresh()
│ ├── 2.4.1 BLF 执行初始化流程
│ │ └── AAC → BLF: blfInstance 初始化
│ │ ├── 2.4.1.1 调用 BeanFactoryPostProcessor
│ │ │ └── BLF: 处理 @Configuration 类(解析 @Bean、@ComponentScan 等注解)
│ │ └── 2.4.1.2 实例化非延迟单例 Bean
│ │ └── BLF: 完成依赖注入、AOP 代理等逻辑
│ └── 2.4.2 发布容器就绪事件
│ └── AAC: 发布 ContextRefreshedEvent(通知监听器容器初始化完成)
五、总结
- 父类优先初始化:遵循 Java 类加载机制,先完成父类AbstractApplicationContext和GenericApplicationContext的基础架构初始化(如BeanFactory创建)。
- 注解驱动:通过AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner解析注解,将配置类和组件类转换为BeanDefinition。
六、带注释的源码地址(5.3.33版本)