0%

获取bean

Spring 获取 Bean 完整流程源码解析:从 getBean 到 Bean 就绪

Spring 容器获取 Bean 的核心入口是 getBean() 方法,但其底层逻辑完全封装在 doGetBean() 中 —— 这是 Spring IOC 容器实现 “Bean 查找、创建、依赖注入、初始化” 的核心方法。从 “入口触发→Bean 名称处理→缓存查找(三级缓存)→循环依赖处理→不同作用域 Bean 创建→属性注入与初始化” 六个维度,逐行拆解获取 Bean 的全流程。

核心入口:getBean()doGetBean()

getBean() 是用户调用的入口方法,但其仅做简单转发,真正的逻辑全部在 doGetBean() 中实现。这一设计遵循 “职责单一” 原则 ——getBean() 暴露接口,doGetBean() 封装复杂逻辑。

1. 入口方法调用链

1
2
3
4
5
6
7
8
9
// 1. 用户调用:从容器获取 Bean(示例)
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Car car = (Car) context.getBean("car"); // 入口1:调用 ApplicationContext 的 getBean()

// 2. ApplicationContext 继承 BeanFactory,最终委托给 AbstractBeanFactory 的 getBean()
// AbstractBeanFactory#getBean(String name)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false); // 入口2:转发到 doGetBean()
}

2. doGetBean():获取 Bean 的 “总控制器”

doGetBean() 是整个流程的核心,代码虽长,但逻辑清晰,可拆解为 8 个关键步骤,每个步骤对应特定职责:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
protected <T> T doGetBean(
final String name, // 用户传入的 Bean 名称(可能是别名/FactoryBean)
final Class<T> requiredType, // 期望的 Bean 类型(用于类型转换)
final Object[] args, // 构造方法参数(创建 Bean 时用)
boolean typeCheckOnly // 是否仅做类型检查(不创建 Bean)
) throws BeansException {

// ========================= 步骤1:处理 Bean 名称,得到真实 beanName =========================
final String beanName = transformedBeanName(name);
Object bean;

// ========================= 步骤2:从缓存查找单例 Bean(解决循环依赖) =========================
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 处理 FactoryBean:返回 FactoryBean 生成的目标对象(而非 FactoryBean 本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

// ========================= 步骤3:缓存未命中,处理非单例/未创建的单例 =========================
else {
// 3.1 原型 Bean 循环依赖检查(原型无法解决循环依赖,直接报错)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 3.2 父容器查找(若当前容器无该 BeanDefinition,委托父容器查找)
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name); // 恢复原始名称(如 &前缀)
return (T) parentBeanFactory.getBean(nameToLookup, args); // 父容器递归查找
}

// 3.3 标记 Bean 为“已创建”(避免重复创建)
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
// 3.4 合并 BeanDefinition(处理父子 Bean 继承,如 parent 属性)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); // 校验 BeanDefinition

// 3.5 初始化当前 Bean 依赖的其他 Bean(dependsOn 配置)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查循环依赖(如 A depends-on B,B depends-on A)
if (isDependent(beanName, dep)) {
throw new BeanCreationException("循环依赖:" + beanName + " ↔ " + dep);
}
registerDependentBean(dep, beanName); // 注册依赖关系
getBean(dep); // 递归初始化被依赖的 Bean
}
}

// ========================= 步骤4:根据作用域创建 Bean =========================
// 4.1 单例 Bean(核心:缓存+全局唯一)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args); // 真正创建单例 Bean
} catch (BeansException ex) {
destroySingleton(beanName); // 创建失败,清理缓存
throw ex;
}
}
});
// 处理 FactoryBean:返回目标对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

// 4.2 原型 Bean(每次 getBean() 都创建新实例)
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName); // 标记原型 Bean 开始创建
prototypeInstance = createBean(beanName, mbd, args); // 创建新实例
} finally {
afterPrototypeCreation(beanName); // 标记原型 Bean 创建完成
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

// 4.3 其他作用域(如 request、session,需自定义 Scope 实现)
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("未注册作用域:" + scopeName);
}
try {
// 委托 Scope 接口创建 Bean(如 request 作用域绑定到当前请求)
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException("作用域 " + scopeName + " 未激活");
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName); // 创建失败,清理资源
throw ex;
}
}

// ========================= 步骤5:类型检查与转换 =========================
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
// 类型转换(如 String → Integer,依赖 ConversionService)
return getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}

return (T) bean;
}

关键步骤深度拆解

步骤 1:transformedBeanName()—— 处理 Bean 名称

用户传入的 name 可能是别名FactoryBean 名称(带 & 前缀),需转换为 “真实 beanName”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// AbstractBeanFactory#transformedBeanName
protected String transformedBeanName(String name) {
// 1. 移除 FactoryBean 前缀 &(如 &userFactory → userFactory)
String beanName = BeanFactoryUtils.transformedBeanName(name);
// 2. 解析别名(从 aliasMap 中获取原始 beanName,如 "carAlias" → "car")
if (this.aliasMap.containsKey(beanName)) {
String canonicalName;
do {
canonicalName = this.aliasMap.get(beanName);
beanName = canonicalName;
} while (this.aliasMap.containsKey(beanName));
}
return beanName;
}
  • FactoryBean 前缀 &&userFactory 表示获取 UserFactory 本身,而非其 getObject() 生成的 User 对象;
  • 别名解析:Spring 允许通过 <alias name="car" alias="carAlias"/> 配置别名,此处需递归解析到原始 beanName。

步骤 2:getSingleton()—— 三级缓存与循环依赖解决

Spring 用三级缓存存储单例 Bean 的不同状态,核心目标是解决单例 Bean 的循环依赖(如 A 依赖 B,B 依赖 A),原型 Bean 因无缓存无法解决循环依赖。

(1)三级缓存定义
1
2
3
4
// AbstractBeanFactory 的父类 DefaultSingletonBeanRegistry 中定义
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存:完整单例 Bean(id→实例)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存:Bean 工厂(id→ObjectFactory)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存:早期单例 Bean(未完成属性注入,id→实例)
(2)getSingleton() 缓存查找逻辑
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
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 先查一级缓存:是否存在完整的单例 Bean
Object singletonObject = this.singletonObjects.get(beanName);

// 2. 一级缓存无,且当前 Bean 正在创建(可能存在循环依赖)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) { // 同步锁:避免并发问题
// 3. 查二级缓存:是否存在早期 Bean(未完成属性注入)
singletonObject = this.earlySingletonObjects.get(beanName);

// 4. 二级缓存无,且允许早期引用(循环依赖场景)
if (singletonObject == null && allowEarlyReference) {
// 5. 查三级缓存:获取 Bean 工厂(ObjectFactory)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 6. 调用 ObjectFactory.getObject():生成早期 Bean(未注入属性)
singletonObject = singletonFactory.getObject();
// 7. 早期 Bean 移到二级缓存,删除三级缓存(避免重复生成)
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
(3)三级缓存解决循环依赖示例(A 依赖 B,B 依赖 A)
  1. 创建 A:调用 doCreateBean(A),实例化 A 后,将 ObjectFactory(A) 放入三级缓存;
  2. A 注入 B:A 需注入 B,调用 getBean(B)
  3. 创建 B:调用 doCreateBean(B),实例化 B 后,将 ObjectFactory(B) 放入三级缓存;
  4. B 注入 A:B 需注入 A,调用 getBean(A)
  5. 查找 A:从三级缓存获取 ObjectFactory(A),生成早期 A(未注入属性),放入二级缓存;
  6. B 初始化完成:B 注入早期 A 后,完成初始化,放入一级缓存;
  7. A 注入 B:A 从一级缓存获取完整 B,完成属性注入,放入一级缓存。

核心结论:三级缓存通过 “提前暴露未完成初始化的 Bean”,打破了单例 Bean 的循环依赖死锁。

步骤 3:getObjectForBeanInstance()—— 处理 FactoryBean

Spring 中 Bean 分为普通 BeanFactoryBean

  • 普通 Bean:直接返回实例;
  • FactoryBean:返回其 getObject() 生成的目标对象(需特殊处理)。
源码逻辑拆解
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
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

// 1. 若名称带 & 但实例不是 FactoryBean → 报错(非法使用 & 前缀)
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}

// 2. 普通 Bean 或用户明确获取 FactoryBean 本身(带 &)→ 直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}

// 3. 处理 FactoryBean:生成目标对象
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName); // 查 FactoryBean 缓存
}

if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 合并 BeanDefinition(处理父子继承)
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
// 判断是否为 Spring 内部合成的 FactoryBean(如 AOP 代理)
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 核心:调用 FactoryBean.getObject() 生成目标对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}

return object;
}
关键细节
  • FactoryBean 缓存:单例 FactoryBean 生成的目标对象会存入 factoryBeanObjectCache,避免重复调用 getObject()
  • & 前缀作用getBean("&userFactory") 返回 UserFactory 本身,getBean("userFactory") 返回 userFactory.getObject() 生成的 User 对象。

步骤 4:createBean()doCreateBean()——Bean 实例化与初始化

当缓存无 Bean 且需新建时,createBean() 是入口,实际逻辑在 doCreateBean() 中,包含 “实例化→属性注入→初始化” 三大核心环节。

(1)doCreateBean() 核心流程
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// ========================= 环节1:实例化 Bean(创建空对象) =========================
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); // 清理 FactoryBean 缓存
}
if (instanceWrapper == null) {
// 核心:通过构造器/工厂方法创建 Bean 实例(未注入属性)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance(); // 原始 Bean 实例
Class<?> beanType = instanceWrapper.getWrappedClass();
mbd.resolvedTargetType = beanType;

// ========================= 环节2:处理 Merged BeanDefinition(注解解析) =========================
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
// 核心:处理 @Autowired、@Value 等注解(AutowiredAnnotationBeanPostProcessor 生效)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}

// ========================= 环节3:提前暴露 Bean(解决循环依赖) =========================
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 把 Bean 工厂放入三级缓存(循环依赖时,其他 Bean 可通过工厂获取早期实例)
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 对早期 Bean 应用后置处理(如 AOP 代理)
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}

// ========================= 环节4:属性注入(填充依赖) =========================
Object exposedObject = bean;
try {
// 核心:注入属性(处理 <property>、@Autowired、自动注入 byName/byType)
populateBean(beanName, mbd, instanceWrapper);

// ========================= 环节5:初始化 Bean(增强与回调) =========================
if (exposedObject != null) {
// 核心:执行 Aware 接口、BeanPostProcessor、init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable ex) {
throw new BeanCreationException("Bean 初始化失败", ex);
}

// ========================= 环节6:注册销毁方法(如 destroy-method) =========================
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException("销毁方法配置错误", ex);
}

return exposedObject;
}
(2)关键子环节详解
createBeanInstance():实例化 Bean

通过以下方式创建空对象(未注入属性):

  • 构造器实例化:默认无参构造器,或根据 constructor-arg 匹配有参构造器;
  • 工厂方法实例化:静态工厂(factory-method)或实例工厂(factory-bean + factory-method)。
populateBean():属性注入

核心是 “将依赖的 Bean 或简单值注入到当前 Bean 的属性中”,支持三种注入方式:

  1. XML 显式配置<property name="userDao" ref="userDao"/>
  2. 自动注入autowire="byName"(按属性名匹配 Bean)或 autowire="byType"(按属性类型匹配 Bean);
  3. 注解注入@Autowired(由 AutowiredAnnotationBeanPostProcessor 处理)、@Value(解析 SpEL 表达式)。

源码关键逻辑:

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
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 处理 InstantiationAwareBeanPostProcessor(如 @Autowired 注入前的准备)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 终止注入(如自定义注入逻辑已处理)
}
}
}
}

// 2. 自动注入(byName/byType)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(mbd.getPropertyValues());
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs); // 按属性名匹配 Bean
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs); // 按属性类型匹配 Bean
}
mbd.setPropertyValues(newPvs);
}

// 3. 应用属性值到 Bean(最终调用 setXxx() 方法注入)
applyPropertyValues(beanName, mbd, bw, mbd.getPropertyValues());
}
initializeBean():初始化 Bean

Bean 实例化并注入属性后,执行初始化逻辑,按以下顺序执行:

  1. Aware 接口回调:注入容器服务(如 BeanNameAwareApplicationContextAware);
  2. BeanPostProcessor 前置处理postProcessBeforeInitialization()(如 @PostConstruct 注解执行);
  3. 初始化方法InitializingBean.afterPropertiesSet() → XML/@Bean 配置的 init-method
  4. BeanPostProcessor 后置处理postProcessAfterInitialization()(AOP 代理生成在此处)。

源码逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 接口回调(如 BeanNameAware.setBeanName())
invokeAwareMethods(beanName, bean);

// 2. BeanPostProcessor 前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// 3. 执行初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException("初始化方法执行失败", ex);
}

// 4. BeanPostProcessor 后置处理(AOP 代理生成)
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

不同作用域 Bean 的创建差异

Spring 支持多种 Bean 作用域,核心差异在于 “实例数量” 和 “生命周期管理”,doGetBean() 中针对不同作用域有不同处理逻辑:

作用域 实例数量 生命周期管理 创建逻辑关键点
singleton(单例) 容器内唯一 容器启动时创建(非懒加载),容器关闭时销毁 存入 singletonObjects 缓存,仅创建一次
prototype(原型) 每次 getBean() 新实例 实例化后容器不再管理(需手动销毁) 不缓存,每次调用 createBean() 生成新实例
request 每个 HTTP 请求新实例 请求结束时销毁 委托 RequestScope 绑定到当前请求
session 每个 HTTP Session 新实例 Session 过期时销毁 委托 SessionScope 绑定到当前 Session

总结:获取 Bean 的完整链路

Spring 获取 Bean 的流程本质是 “先查缓存→再处理依赖→最后创建实例”,可精简为 10 步:

  1. 调用 getBean(name),转发到 doGetBean()
  2. transformedBeanName():解析别名和 FactoryBean 前缀,得到真实 beanName;
  3. getSingleton(beanName):从三级缓存查找单例 Bean,存在则返回;
  4. 检查原型循环依赖,存在则报错;
  5. 若父容器存在且当前容器无该 BeanDefinition,委托父容器查找;
  6. 处理 dependsOn:递归 getBean() 初始化被依赖的 Bean;
  7. 根据作用域创建 Bean:
    • 单例:调用 getSingleton() 传入 ObjectFactory,内部调用 createBean()
    • 原型:直接调用 createBean() 生成新实例;
  8. doCreateBean():
    • createBeanInstance():实例化 Bean(空对象);
    • applyMergedBeanDefinitionPostProcessors():解析 @Autowired 等注解;
    • 提前暴露 Bean 到三级缓存(解决循环依赖);
    • populateBean():属性注入;
    • initializeBean():执行 Aware 回调、BeanPostProcessor、init-method;
  9. getObjectForBeanInstance():若为 FactoryBean,返回其 getObject() 生成的目标对象;
  10. 类型转换:将 Bean 转换为用户期望的类型,返回给用户

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