Spring Bean的实例化 - 从源码角度进行全解析

Spring Bean的实例化 - 从源码角度进行全解析

一、引言

​ 在Spring中,一个Bean的“一生”要经历定义解析、实例化、属性填充、初始化、销毁等多个阶段。而我们今天的主角——实例化,是指容器通过反射或工厂方法,为Bean分配内存空间,并创建一个原始对象的过程

这个过程的宏观起点,通常是从ApplicationContextrefresh()方法开始的。对于非懒加载的单例Bean,实例化的统一入口在finishBeanFactoryInitialization方法中。

1
2
3
4
5
6
7
// AbstractApplicationContext.java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ... 其他初始化工作 ...

// 核心入口:实例化所有剩余的非懒加载单例Bean
beanFactory.preInstantiateSingletons();
}

从这里开始,Spring将遍历所有已注册的BeanDefinition,并逐一调用getBean()来触发实例化流程。我们将跟随这条主线,深入每一个细节。

二:从 getBean()createBean()

2.1 doGetBean()

getBean()方法是获取Bean的入口,但其真正的实现逻辑在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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// AbstractBeanFactory.java
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {

// 1. 处理 Bean 名称,去除 & 前缀等
String beanName = transformedBeanName(name);
Object sharedInstance = getSingleton(beanName); // 尝试从缓存中获取

if (sharedInstance != null && args == null) {
// 缓存命中,直接返回(可能需要进行 FactoryBean 处理)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 缓存未命中,开始真正的创建流程
// 2. 检查循环依赖(原型模式下的循环依赖检测)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 3. 检查父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
// ...

// 4. 将当前 Bean 标记为正在创建(用于循环依赖检测)
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
// 5. 合并父 BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// 6. 处理 DependsOn 依赖(确保依赖的 Bean 先实例化)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);
getBean(dep); // 强制初始化依赖 Bean
}
}

// 7. 根据不同作用域创建 Bean(核心逻辑)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 这里就是创建单例 Bean 的核心回调
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 原型模式的处理
// ...
} else {
// Request、Session 等其他作用域
// ...
}
} catch (BeansException ex) {
// ...
}
}
return (T) bean;
}

在这个漫长的前奏中,最重要的收获是:Spring通过三级缓存尝试获取提前暴露的Bean(解决循环依赖),并最终通过回调的方式,触发了createBean()方法。

1.2 getSingleton()

doGetBean()开始时调用的getSingleton(beanName),对应的是DefaultSingletonBeanRegistry中的三级缓存机制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一级缓存:完全实例化并初始化好的 Bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 二级缓存:早期暴露的 Bean(尚未属性填充和初始化)
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 三级缓存:单例工厂(用于生成早期引用,解决 AOP 代理问题)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 将早期引用从三级缓存移到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
return singletonObject;
}

这个三级缓存的巧妙设计,是Spring解决循环依赖的基石。在实例化阶段,我们只需记住:当一个Bean正在创建时,它的“早期引用”可能会通过三级缓存暴露给其他依赖它的Bean

三、createBean()

​ 当缓存中不存在Bean,且作用域为单例时,getSingleton(String, ObjectFactory) 方法会调用传入的 ObjectFactorygetObject() 方法,也就是下面的 createBean() 方法。

createBean()是整个实例化流程的总指挥,它位于AbstractAutowireCapableBeanFactory中。

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
// AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// 1. 解析 Bean 的 Class 对象(根据 className 或 beanClass)
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// 2. 准备方法覆写(Lookup Method / Replace Method)的验证
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(...);
}

// 3. 核心扩展点:给 BeanPostProcessors 一个机会返回代理对象以代替目标 Bean 的实例化
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 如果这里返回了非空对象,则后续的 doCreateBean 流程将被跳过
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(...);
}

// 4. 真正的创建逻辑
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} catch (Throwable ex) {
// ...
}
}

3.1 前置拦截:resolveBeforeInstantiation()

​ 这个方法是一个极其重要的扩展点。它会调用实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// AbstractAutowireCapableBeanFactory.java
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 调用所有 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 如果上面返回了非 null 对象,立即执行初始化后的后置处理(postProcessAfterInitialization)
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

​ 这个机制的意义在于:允许用户在Bean被实例化之前,自己生成一个对象返回。典型的应用场景包括:AOP动态代理、模拟对象等。如果这个钩子返回了一个对象,那么后续的doCreateBean()将不会执行,Bean的“实例化”就此打住

四:doCreateBean() —— 实例化核心流程

doCreateBean()是Spring中最复杂、最重要的方法之一。它囊括了实例化、属性填充、初始化等全生命周期,但今天我们只聚焦于实例化这一步。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

// 实例化阶段的核心数据结构:BeanWrapper
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 如果是单例,尝试清除工厂缓存(避免 FactoryBean 的干扰)
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// ★★★ 核心:创建 Bean 实例 ★★★
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取刚刚通过反射创建的原始对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();

// ... 省略后续代码(属性填充、初始化等)...
}

可以看到,实例化的核心实现委托给了 createBeanInstance() 方法。

4.1 createBeanInstance():选择合适的实例化策略

这个方法的目标很明确:给我一个 RootBeanDefinition,我还你一个 BeanWrapper(包装了原始对象的反射工具类)。Spring提供了多种实例化方式,按优先级排序如下:

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
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 1. 确保 BeanDefinition 中已经加载了 Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);

// 2. 校验:如果 Class 是 public,且不允许非 public 访问构造器,且安全检查失败等
// ...

// 3. ★★★ 方式一:使用 Supplier 创建实例(Spring 5.0 新增)★★★
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}

// 4. ★★★ 方式二:使用工厂方法创建实例(@Bean 配置、XML 中的 factory-method)★★★
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// 5. 处理同一个类的多个构造器的情况
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
// 缓存机制:如果之前已经解析过构造函数,直接从缓存取
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 5.1 方式三:有参构造器自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 5.2 方式四:默认无参构造器
return instantiateBean(beanName, mbd);
}
}

// 6. ★★★ 方式五:推断构造器(最复杂、最核心的场景)★★★
// 通过 BeanPostProcessor 推断出要使用的构造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR
|| mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 如果有候选构造器,或者配置了构造器自动注入模式,或者定义了构造器参数值,则使用有参构造器逻辑
return autowireConstructor(beanName, mbd, ctors, args);
}

// 7. 默认兜底:使用默认无参构造器
return instantiateBean(beanName, mbd);
}

这个方法的逻辑非常清晰,像是一个路由器,根据不同的配置将请求分发给不同的处理器

4.1.1 方式一:Supplier 创建

Spring 5.0 引入,允许通过编程方式提供一个 Supplier 来创建实例,非常灵活。

4.1.2 方式二:工厂方法

对应配置中的 factory-method。如果是静态工厂方法,直接调用;如果是实例工厂方法,则需要先实例化工厂Bean。

4.1.3 方式五:构造器推断 —— determineConstructorsFromBeanPostProcessors()

这是注解驱动开发中(如 @Autowired 标注在构造器上)最常用的方式。它会调用 SmartInstantiationAwareBeanPostProcessordetermineCandidateConstructors() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// AbstractAutowireCapableBeanFactory.java
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 让后置处理器去推断构造器(例如 AutowiredAnnotationBeanPostProcessor)
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}

AutowiredAnnotationBeanPostProcessor 为例,它会扫描类中的构造器,如果找到唯一的一个有参构造器,或者某个构造器被 @Autowired 标注,则将其作为候选返回 。

4.2 无参实例化:instantiateBean()

如果确定使用默认无参构造器,流程会走到这里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
// 获取实例化策略
if (System.getSecurityManager() != null) {
// ...
} else {
// 调用 SimpleInstantiationStrategy 进行实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 包装成 BeanWrapper 并返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(...);
}
}

4.2.1 SimpleInstantiationStrategy.instantiate()

真正的反射调用在这里发生。

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
// SimpleInstantiationStrategy.java
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 如果没有方法覆写(lookup-method/replace-method),直接使用反射
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 获取默认无参构造器
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
constructorToUse = clazz.getDeclaredConstructor();
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Exception ex) {
// ...
}
}
}
// 反射创建实例
return BeanUtils.instantiateClass(constructorToUse);
} else {
// 如果有方法覆写,必须使用 CGLIB 来生成子类,以覆写对应方法
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

这里有个重要细节:如果 Bean 中配置了 <lookup-method><replaced-method>,Spring 不能直接使用反射创建原始对象,而是必须通过 CGLIB 动态生成一个子类,并在子类中实现方法的覆写逻辑

4.3 有参实例化:autowireConstructor()

这是最复杂的分支,涉及到构造器的匹配、参数值的解析和类型转换。

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
// ConstructorResolver.java (autowireConstructor 方法逻辑)
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

// 新建一个 BeanWrapperImpl 准备包装结果
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

// 1. 确定要使用的构造器
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;

// 2. 如果外部传入了参数 explicitArgs,则直接用
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
// 3. 否则,尝试从缓存中获取已解析过的构造器
// ...
}

// 4. 如果没有缓存,开始解析构造器
if (constructorToUse == null) {
// 获取所有候选构造器
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}

// 5. 对构造器进行排序(按修饰符 public 优先,然后参数个数降序)
AutowireUtils.sortConstructors(candidates);

// 6. 用于记录最小参数个数(用于匹配)
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;

// 7. 遍历所有候选构造器
for (Constructor<?> candidate : candidates) {
// 获取构造器参数类型数组
Class<?>[] paramTypes = candidate.getParameterTypes();

// 8. 确定本次构造器调用需要的参数值
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// 如果已经找到构造器,且当前构造器参数更少,则跳过(因为我们已经按参数个数降序排序)
break;
}
if (paramTypes.length < minNrOfArgs) {
// 参数个数少于最小要求,跳过
continue;
}

ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
// ★★★ 核心:将 BeanDefinition 中定义的参数值(如 <constructor-arg>)解析为具体的对象 ★★★
String autowiredBeanName = null;
Object value = null;

// 根据参数类型、索引、名称等,从 resolvedValues 中获取对应的值
// 如果参数需要自动装配(如引用其他 Bean),这里会触发 getBean() 去获取依赖的 Bean
// 如果参数是简单类型,会进行类型转换
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, methodHolder);
} catch (BeansException ex) {
throw ex;
}
} else {
// 没有配置参数值,但构造器需要参数,则使用默认值(null 或 简单类型默认值)
argsHolder = new ArgumentsHolder(paramTypes.length);
// ...
}

// 9. 计算类型差异权重:判断当前解析出的参数值类型与构造器参数类型的匹配程度
int typeDiffWeight = argsHolder.getTypeDifferenceWeight(paramTypes);
if (typeDiffWeight < minTypeDiffWeight) {
// 找到了更匹配的构造器
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
} else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 存在两个同样匹配的构造器,标记为歧义
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}

// 10. 处理歧义或未找到构造器的情况
if (constructorToUse == null) {
throw new BeanCreationException(...);
} else if (ambiguousConstructors != null) {
throw new BeanCreationException(...);
}

// 11. 将解析结果存入缓存
if (explicitArgs == null && argsHolderToUse != null) {
mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
mbd.constructorArgumentsResolved = true;
mbd.constructorArgumentValues = argsHolderToUse;
}
}

// 12. ★★★ 最终实例化:通过反射调用构造器 ★★★
try {
Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
bw.setBeanInstance(beanInstance);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(...);
}
}

整个autowireConstructor过程可以概括为:穷举 -> 解析参数 -> 计算权重 -> 选出最优 -> 反射调用。这也是Spring为什么能智能地根据你提供的参数自动匹配合适构造器的原因 。

4.3.1 参数解析的深度:createArgumentArray()

在解析参数值时,如果参数是引用类型(如另一个Bean),Spring会递归调用getBean()去创建或获取依赖的Bean。这正是依赖注入在实例化阶段的体现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ConstructorResolver.java
private ArgumentsHolder createArgumentArray(...) {
// ... 遍历所有参数位置
for (int i = 0; i < paramTypes.length; i++) {
// 获取构造器参数值定义
ValueHolder valueHolder = resolvedValues.getArgumentValue(i, paramTypes[i], ...);
if (valueHolder == null) {
// 没有显式定义,尝试自动装配
autowiredBeanName = resolveAutowiredArgument(paramTypes[i], ...);
// 这里会调用 beanFactory.getBean(autowiredBeanName)
} else {
// 将配置的值(可能是字符串)转换为目标类型
convertedValue = beanFactory.convertIfNecessary(valueHolder.getValue(), paramTypes[i]);
}
// ...
}
}

五、实例化后—— 早期暴露与循环依赖

​ 对象被createBeanInstance()成功创建出来后,在doCreateBean()中,还有一步与实例化密切相关的重要操作:提前暴露早期引用

1
2
3
4
5
6
7
8
9
10
11
// AbstractAutowireCapableBeanFactory.doCreateBean() 中,在实例化之后、属性填充之前
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 将当前刚实例化完的、尚未填充属性的原始对象,以一个 ObjectFactory 的形式添加到三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

getEarlyBeanReference() 方法会调用 SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference(),这是解决 AOP 代理与循环依赖冲突的关键。如果 Bean 需要被代理,这里返回的就是代理对象的早期引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// AbstractAutowireCapableBeanFactory.java
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 例如:AbstractAutoProxyCreator 会在这里返回代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}

至此,一个原始的、可能尚未填充属性的 Bean 实例已经躺在三级缓存中,随时准备为它的“兄弟们”解决循环依赖问题。

六、实例化策略——InstantiationStrategy

回顾整个实例化过程,无论是无参构造器、有参构造器还是工厂方法,最终创建对象的操作都委托给了InstantiationStrategy。这是一个策略接口,有两个主要实现:

  1. **SimpleInstantiationStrategy**:支持通过反射实例化,不支持方法注入。
  2. **CglibSubclassingInstantiationStrategy**(默认使用):继承自SimpleInstantiationStrategy,增加了通过 CGLIB 生成子类来支持方法注入的能力。

当检测到RootBeanDefinition中存在methodOverrides时,策略实现类会这样处理:

1
2
3
4
5
6
7
8
9
10
11
// CglibSubclassingInstantiationStrategy 的内部类 CglibSubclassCreator
public Object instantiate(Constructor<?> ctor, Object... args) {
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.beanDefinition.getBeanClass());
// 设置回调,拦截配置了 lookup-method 和 replace-method 的方法
enhancer.setCallbackTypes(new Class[]{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class});

// 生成子类并创建实例
return enhancer.create();
}

这意味着,如果一个普通的单例 Bean 没有使用方法注入,它仍然是通过反射创建的,性能很高;只有必要时才启用 CGLIB。

七、总结

getBean()到最终对象的诞生,Spring Bean 的实例化流程是一条设计精密的流水线。我们可以将其核心逻辑概括为以下流程:

  1. 入口统一:所有实例化始于getBean(),经过doGetBean()的复杂预处理(处理依赖、作用域、父工厂)。
  2. 前置拦截resolveBeforeInstantiation 提供了在实例化前直接返回代理对象的扩展点。
  3. 策略路由createBeanInstance 根据Supplier、工厂方法、构造器推断、默认无参等条件,选择合适的实例化方式。
  4. 构造器推断autowireConstructor 通过复杂的权重计算和参数解析,智能地选出最佳构造器。
  5. 反射/CGLIB:最终通过InstantiationStrategy,利用反射或CGLIB技术,在内存中开辟空间,构建出原始对象。
  6. 提前暴露:实例化后的原始对象会被包装成ObjectFactory放入三级缓存,为后续可能的循环依赖做好准备。

这不仅仅是“new一个对象”那么简单。Spring 通过这一系列精巧的设计,将控制反转依赖注入的理念落到了实处,既保证了灵活性(丰富的扩展点),又兼顾了性能(反射缓存、策略选择)。


Spring Bean的实例化 - 从源码角度进行全解析
https://johnjoyjzw.github.io/2024/11/12/Spring Bean的实例化-从源码角度进行全解析/
Author
JiangZW
Posted on
November 12, 2024
Licensed under