0%

源码分析之上下文构建

Spring 上下文构建源码深度解析:从 ClassPathXmlApplicationContext 到 IOC 容器就绪

Spring 上下文(ApplicationContext)是 IOC 容器的核心载体,负责配置加载、BeanDefinition 管理、Bean 实例化与初始化的全流程。以 ClassPathXmlApplicationContext 为例,其初始化过程围绕 refresh() 方法展开,这是 Spring 最核心的源码链路之一。从 “构造函数初始化→refresh() 全景流程→关键子流程拆解→核心设计思想” 四个维度,彻底讲透上下文构建的每一步。

上下文初始化入口:ClassPathXmlApplicationContext 构造函数

创建 ClassPathXmlApplicationContext 实例时,仅需一行代码,但背后触发了完整的初始化流程:

1
ApplicationContext context = new ClassPathXmlApplicationContext("spring-lifecycle.xml");

构造函数核心逻辑

构造函数的本质是 “初始化配置路径 + 触发上下文刷新”,源码如下(已简化关键逻辑):

1
2
3
4
5
6
7
8
// ClassPathXmlApplicationContext 构造函数
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) {
super(parent); // 初始化父上下文(若有)
setConfigLocations(configLocations); // 1. 保存配置文件路径(如 "spring-lifecycle.xml")
if (refresh) {
refresh(); // 2. 核心:触发上下文刷新(IOC 容器初始化的入口)
}
}
  • setConfigLocations:将配置文件路径(支持多个,用逗号分隔)解析为 Spring 可识别的资源路径(如 classpath:spring-lifecycle.xml),并存储到 configLocations 字段;
  • refresh():上下文初始化的 “总开关”,包含 12 个关键步骤,覆盖从 “配置加载” 到 “Bean 就绪” 的全流程。

上下文构建核心:refresh() 方法全景解析

refresh() 方法是 Spring 上下文初始化的 “主流程”,通过同步锁确保线程安全,步骤清晰且环环相扣。其核心目标是 “创建并初始化 IOC 容器,确保所有非懒加载 Bean 就绪”。

refresh() 方法完整流程(带阶段归类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) { // 同步锁:防止并发刷新
// ========================= 阶段1:准备阶段 =========================
prepareRefresh(); // 1. 初始化环境、校验配置、记录启动状态

// ========================= 阶段2:BeanFactory 构建 =========================
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2. 创建/刷新 BeanFactory,注册 BeanDefinition

// ========================= 阶段3:BeanFactory 增强 =========================
prepareBeanFactory(beanFactory); // 3. 填充 BeanFactory 功能(类加载器、SPEL、属性编辑器等)
try {
postProcessBeanFactory(beanFactory); // 4. 子类扩展:BeanFactory 后置处理(空方法,供自定义)
invokeBeanFactoryPostProcessors(beanFactory); // 5. 执行 BeanFactoryPostProcessor(修改 BeanDefinition)
registerBeanPostProcessors(beanFactory); // 6. 注册 BeanPostProcessor(增强 Bean 实例)

// ========================= 阶段4:上下文基础设施初始化 =========================
initMessageSource(); // 7. 初始化国际化消息源
initApplicationEventMulticaster(); // 8. 初始化事件广播器
onRefresh(); // 9. 子类扩展:初始化特殊 Bean(如 Spring MVC 的 DispatcherServlet)
registerListeners(); // 10. 注册事件监听器

// ========================= 阶段5:Bean 实例化与初始化 =========================
finishBeanFactoryInitialization(beanFactory); // 11. 初始化所有非懒加载单例 Bean

// ========================= 阶段6:收尾阶段 =========================
finishRefresh(); // 12. 发布刷新完成事件,标记上下文就绪
} catch (BeansException ex) {
// 异常处理:销毁已创建的 Bean,重置状态
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches(); // 清理缓存(如反射缓存)
}
}
}

各阶段核心目标与关键组件

阶段 核心目标 关键组件 / 方法
准备阶段 初始化环境、校验配置 initPropertySources()validateRequiredProperties()
BeanFactory 构建 创建 BeanFactory 并注册 BeanDefinition refreshBeanFactory()loadBeanDefinitions()
BeanFactory 增强 扩展 BeanFactory 功能,处理后置处理器 BeanFactoryPostProcessorBeanPostProcessor
基础设施初始化 初始化国际化、事件机制 MessageSourceApplicationEventMulticaster
Bean 实例化 生成非懒加载单例 Bean,处理依赖注入 preInstantiateSingletons()doGetBean()、三级缓存
收尾阶段 发布事件,标记上下文就绪 ContextRefreshedEventLifecycleProcessor

关键子流程深度拆解

refresh() 方法中,obtainFreshBeanFactory()(BeanFactory 构建)、invokeBeanFactoryPostProcessors()(后置处理器执行)、finishBeanFactoryInitialization()(Bean 实例化)是最核心的子流程,需深入源码细节。

子流程 1:obtainFreshBeanFactory()—— 创建 BeanFactory 并注册 BeanDefinition

该流程的目标是 “创建 DefaultListableBeanFactory(Spring 最核心的 BeanFactory 实现),并将 XML 配置解析为 BeanDefinition 注册到容器”。

步骤 1.1:refreshBeanFactory()—— 销毁旧工厂,创建新工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// AbstractRefreshableApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
// 1. 若已有 BeanFactory,先销毁并关闭(防止重复初始化)
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 2. 创建 DefaultListableBeanFactory(实现 BeanDefinitionRegistry,支持注册 BeanDefinition)
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId()); // 设置序列化 ID,支持跨容器序列化

// 3. 定制 BeanFactory:允许 BeanDefinition 覆盖、支持循环依赖
customizeBeanFactory(beanFactory);

// 4. 核心:加载 XML 配置,生成 BeanDefinition 并注册
loadBeanDefinitions(beanFactory);

this.beanFactory = beanFactory; // 保存新工厂到上下文
} catch (IOException ex) {
throw new ApplicationContextException("加载配置文件失败", ex);
}
}
步骤 1.2:loadBeanDefinitions()—— 解析 XML 并注册 BeanDefinition

该步骤由 XmlBeanDefinitionReader 完成,核心是 “将 XML 标签(默认标签 / 自定义标签)解析为 BeanDefinition,并注册到 BeanDefinitionRegistry”。

关键逻辑:XML 解析流程
  1. 创建解析器XmlBeanDefinitionReader 关联 BeanFactory,设置资源加载器(ResourceLoader)和实体解析器(EntityResolver);
  2. 加载 XML 资源:将配置文件路径(如 spring-lifecycle.xml)转为 Resource,加载为 Document 对象;
  3. 解析 Document:由DefaultBeanDefinitionDocumentReader处理,区分 “默认标签” 和 “自定义标签”:
    • 默认标签:Spring 内置标签(importaliasbeanbeans),通过 parseDefaultElement() 解析;
    • 自定义标签:如 aop:aspectj-autoproxytx:annotation-driven,通过 NamespaceHandler 解析(从 META-INF/spring.handlers 加载映射关系)。
示例:解析 <bean> 标签(默认标签)
1
2
3
4
5
6
7
8
9
10
11
12
// DefaultBeanDefinitionDocumentReader#parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { // 处理 <import> 标签(导入其他 XML)
importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { // 处理 <alias> 标签(Bean 别名)
processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { // 处理 <bean> 标签(核心)
processBeanDefinition(ele, delegate); // 解析 <bean> 为 BeanDefinition 并注册
} else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 处理 <beans> 标签(嵌套配置)
doRegisterBeanDefinitions(ele);
}
}
注册 BeanDefinition:存入 beanDefinitionMap

解析完成后,BeanDefinition 会被注册到 DefaultListableBeanFactorybeanDefinitionMapConcurrentHashMap<String, BeanDefinition>),键为 Bean id,值为 BeanDefinition(包含类名、属性、作用域等元信息):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// DefaultListableBeanFactory#registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
// 1. 校验 BeanDefinition(如 methodOverrides、factoryMethodName 合法性)
((AbstractBeanDefinition) beanDefinition).validate();

// 2. 处理 BeanDefinition 覆盖(若已存在同 id 的 BeanDefinition,判断是否允许覆盖)
BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException("Bean id 重复:" + beanName);
}
this.beanDefinitionMap.put(beanName, beanDefinition); // 覆盖旧定义
} else {
// 3. 新 BeanDefinition 注册(线程安全处理)
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName); // 记录 Bean id 列表
}
} else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
}
}
}

子流程 2:invokeBeanFactoryPostProcessors()—— 执行 BeanFactory 后置处理器

BeanFactoryPostProcessor 是 Spring 扩展 BeanDefinition 的核心接口,作用是 “在 Bean 实例化前,修改 BeanDefinition 元信息”(如替换 ${} 占位符、动态注册 Bean)。

执行顺序规则

Spring 按优先级执行 BeanFactoryPostProcessor,确保扩展逻辑有序:

  1. BeanDefinitionRegistryPostProcessor(子接口):优先执行,支持动态注册 BeanDefinition;
    • 先执行实现 PriorityOrdered 接口的实例;
    • 再执行实现 Ordered 接口的实例;
    • 最后执行无顺序接口的实例;
  2. 普通 BeanFactoryPostProcessor:后执行,仅修改已注册的 BeanDefinition;
    • 同样按 PriorityOrderedOrdered→无顺序执行。
典型应用:PropertySourcesPlaceholderConfigurer

PropertySourcesPlaceholderConfigurerBeanFactoryPostProcessor 的核心实现,负责 “替换 BeanDefinition 中的 ${key} 占位符”,流程如下:

  1. 加载外部配置文件(如 db.properties);
  2. 遍历 beanDefinitionMap 中的所有 BeanDefinition
  3. PropertyValues 中的 ${key} 占位符(如 ${db.url})替换为配置文件中的值;
  4. 更新 BeanDefinition 的属性值,确保后续实例化时属性正确。

子流程 3:finishBeanFactoryInitialization()——Bean 实例化与初始化

该流程是 “从 BeanDefinition 到可用 Bean 的最后一步”,核心是初始化所有 “非懒加载单例 Bean”,包含 “实例化→属性注入→初始化→AOP 代理” 全链路。

步骤 3.1:preInstantiateSingletons()—— 触发单例 Bean 初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// DefaultListableBeanFactory#preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 所有 Bean id 列表

// 遍历所有 BeanDefinition,初始化非懒加载单例
for (String beanName : beanNames) {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 仅初始化:非抽象、单例、非懒加载的 Bean
if (!mbd.isAbstract() && mbd.isSingleton() && !mbd.isLazyInit()) {
// 处理 FactoryBean:先初始化 FactoryBean 本身,再通过 getObject() 生成目标 Bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit();
if (isEagerInit) {
getBean(beanName); // 初始化目标 Bean
}
} else {
getBean(beanName); // 普通 Bean:调用 getBean() 触发实例化
}
}
}
}
步骤 3.2:getBean()doGetBean()——Bean 实例化核心逻辑

getBean() 是获取 Bean 的入口,实际逻辑在 doGetBean() 中,核心是 “从缓存获取→若不存在则创建”,并通过三级缓存解决单例 Bean 的循环依赖。

三级缓存:解决循环依赖的关键

Spring 通过三个缓存(singletonObjectsearlySingletonObjectssingletonFactories)存储不同状态的单例 Bean,避免循环依赖导致的死锁:

缓存名称 存储内容 作用 优先级(读取顺序)
singletonObjects 完全初始化完成的单例 Bean(id→Bean 实例) 缓存就绪的 Bean,供直接获取 1(一级缓存)
earlySingletonObjects 未完成属性注入的单例 Bean(id→Bean 实例) 提前暴露未初始化完成的 Bean,解决循环依赖 2(二级缓存)
singletonFactories 生成 Bean 的工厂(id→ObjectFactory) 存储 Bean 的创建策略,延迟生成实例 3(三级缓存)
doGetBean() 核心逻辑(简化)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
protected <T> T doGetBean(String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly) {
final String beanName = transformedBeanName(name); // 处理 FactoryBean 的 & 前缀
Object bean;

// 1. 从三级缓存获取已存在的 Bean(优先一级缓存)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); // 处理 FactoryBean
} else {
// 2. 检查循环依赖(原型 Bean 循环依赖直接报错)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 3. 初始化依赖的 Bean(若当前 Bean 依赖其他 Bean,先初始化依赖)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
getBean(dep); // 先初始化依赖的 Bean
}
}

// 4. 根据作用域创建 Bean(单例/原型/其他)
if (mbd.isSingleton()) {
// 单例 Bean:通过 ObjectFactory 创建,加入三级缓存
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args); // 核心:创建 Bean 实例
} catch (BeansException ex) {
destroySingleton(beanName); // 创建失败,销毁已创建的实例
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 原型 Bean:每次 getBean() 都创建新实例
Object prototypeInstance = createBean(beanName, mbd, args);
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
}

return (T) bean;
}
步骤 3.3:createBean()doCreateBean()——Bean 实例化与初始化细节

createBean() 的实际逻辑在 doCreateBean() 中,包含 4 个关键步骤:

  1. 实例化 Bean:通过构造器 / 工厂方法创建 Bean 实例(createBeanInstance());
  2. 提前暴露 Bean:将未初始化的 Bean 加入三级缓存(singletonFactories),解决循环依赖;
  3. 属性注入:填充 Bean 的属性(populateBean()),处理 @Autowired<property> 等注入;
  4. 初始化 Bean:执行 Aware 回调、BeanPostProcessor 前后置处理、init-method(initializeBean())。
initializeBean():Bean 初始化的最后一步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 接口回调:注入容器服务(如 BeanNameAware、ApplicationContextAware)
invokeAwareMethods(beanName, bean);

// 2. BeanPostProcessor 前置处理:初始化前增强(如 @PostConstruct 执行)
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);

// 3. 执行初始化方法:@PostConstruct → InitializingBean#afterPropertiesSet → init-method
invokeInitMethods(beanName, wrappedBean, mbd);

// 4. BeanPostProcessor 后置处理:初始化后增强(AOP 代理生成在此处)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

return wrappedBean;
}
  • AOP 代理生成:Spring AOP 的 AnnotationAwareAspectJAutoProxyCreatorBeanPostProcessor 的实现类,在 applyBeanPostProcessorsAfterInitialization() 中为匹配切面的 Bean 生成代理对象(JDK/CGLIB)。

核心组件与设计思想

1. 关键组件总结

组件 作用 核心实现类
BeanDefinition 存储 Bean 元信息(类名、属性、作用域等) RootBeanDefinitionGenericBeanDefinition
BeanDefinitionRegistry 注册 / 管理 BeanDefinition DefaultListableBeanFactory
BeanFactoryPostProcessor 修改 BeanDefinition(实例化前) PropertySourcesPlaceholderConfigurerConfigurationClassPostProcessor
BeanPostProcessor 增强 Bean 实例(实例化后) AutowiredAnnotationBeanPostProcessorAnnotationAwareAspectJAutoProxyCreator
ApplicationContext 上下文容器,集成 BeanFactory 与额外功能 ClassPathXmlApplicationContextAnnotationConfigApplicationContext

2. 核心设计思想

  • 开闭原则:通过 BeanFactoryPostProcessorBeanPostProcessor 等扩展接口,允许开发者扩展容器功能,无需修改 Spring 核心源码;
  • 依赖注入(DI):通过 BeanDefinition 管理依赖关系,在 populateBean() 中自动注入,降低组件耦合;
  • 循环依赖解决:通过三级缓存提前暴露未初始化的 Bean,避免单例 Bean 循环依赖导致的死锁;
  • 事件驱动:通过 ApplicationEventMulticasterApplicationListener 实现事件发布与监听,解耦业务逻辑;
  • 懒加载与预加载:单例 Bean 默认预加载(容器启动时初始化),可通过 @Lazy 延迟到首次使用时初始化,平衡启动速度与内存占用。

总结:上下文构建的核心链路

Spring ClassPathXmlApplicationContext 的构建过程,本质是 “从 XML 配置到可用 Bean 的转化链路”,可精简为 5 步:

  1. 配置加载XmlBeanDefinitionReader 读取 XML,解析为 BeanDefinition
  2. BeanDefinition 注册:将 BeanDefinition 存入 DefaultListableBeanFactorybeanDefinitionMap
  3. 容器增强BeanFactoryPostProcessor 修改 BeanDefinitionBeanPostProcessor 注册到容器;
  4. Bean 实例化preInstantiateSingletons() 初始化非懒加载单例 Bean,通过 doGetBean() 调用 createBean() 完成 “实例化→注入→初始化→代理”;
  5. 上下文就绪:发布 ContextRefreshedEvent,标记 IOC 容器可用

欢迎关注我的其它发布渠道