二十二、创建Bean之实例化Bean对象二

创建Bean之实例化Bean对象二

createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args)` 方法,用于实例化 Bean 对象。它会根据不同情况,选择不同的实例化策略来完成 Bean 的初始化,主要包括:

  • Supplier 回调:obtainFromSupplier(final String beanName, final RootBeanDefinition mbd) 方法。
  • 工厂方法初始化:instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) 方法。
  • 构造函数自动注入初始化:autowireConstructor(final String beanName, final RootBeanDefinition mbd, Constructor[] chosenCtors, final Object[] explicitArgs) 方法。
  • 默认构造函数注入:instantiateBean(final String beanName, final RootBeanDefinition mbd) 方法。

autowireConstructor()

这个初始化方法,我们可以简单理解为是带有参数的构造方法,来初始化 Bean 对象。

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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// AbstractAutowireCapableBeanFactory.java

protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

// ConstructorResolver.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

// 封装 BeanWrapperImpl 对象,并完成初始化
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

// 获得 constructorToUse、argsHolderToUse、argsToUse
Constructor<?> constructorToUse = null;// 构造函数
ArgumentsHolder argsHolderToUse = null;// 构造参数
Object[] argsToUse = null;// 构造参数

// 确定构造参数
// 如果 getBean() 已经传递,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
// 尝试从缓存中获取
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 缓存中的构造函数或者工厂方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 缓存中的构造参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 缓存中存在,则解析存储在 BeanDefinition 中的参数
// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}

// 没有缓存,则尝试从配置文件中获取参数
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// 如果 chosenCtors 未传入,则获取构造方法们
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}

//创建 Bean
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}

// Need to resolve the constructor.
// 是否需要解析构造器
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 用于承载解析后的构造函数参数的值
ConstructorArgumentValues resolvedValues = null;

int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 从 BeanDefinition 中获取构造参数,也就是从配置文件中提取构造参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

// 对构造函数进行排序处理
// public 构造函数优先参数数量降序,非public 构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
// 最小参数类型权重
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;

// 迭代所有构造函数
for (Constructor<?> candidate : candidates) {
// 获取该构造函数的参数类型
int parameterCount = candidate.getParameterCount();

// 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数,则终止。
// 因为,已经按照参数个数降序排列了
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 参数个数不等,继续
if (parameterCount < minNrOfArgs) {
continue;
}

// 参数持有者 ArgumentsHolder 对象
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
// 注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
// 获取构造函数、方法参数的探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 通过探测器获取构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据构造函数和构造参数,创建参数持有者 ArgumentsHolder 对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// 若发生 UnsatisfiedDependencyException 异常,添加到 causes 中。
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;// continue ,继续执行
}
}
else {
// 构造函数没有参数
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
// 根据 explicitArgs ,创建 ArgumentsHolder 对象
argsHolder = new ArgumentsHolder(explicitArgs);
}

// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 如果它代表着当前最接近的匹配则选择其作为构造函数
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);
}
}

// 没有可执行的工厂方法,抛出异常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}

// 将解析的构造函数加入缓存
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}

Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 创建 Bean 对象,并设置到 bw 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
  • 一句话概括:首先确定构造函数参数、构造函数,然后调用相应的初始化策略进行 bean 的初始化。关于如何确定构造函数、构造参数,该部分逻辑和 instantiateUsingFactoryMethod(...) 方法,基本一致。
instantiate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {

try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
this.beanFactory.getAccessControlContext());
}
else {
return this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via factory method failed", ex);
}
}
  • 首先,是获取实例化 Bean 的策略 InstantiationStrategy 对象。
  • 然后,调用其 instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Constructor ctor, Object... args) 方法,该方法在 SimpleInstantiationStrategy 中实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// SimpleInstantiationStrategy.java

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,final Constructor<?> ctor, Object... args) {

// <x1> 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
// 设置构造方法,可访问
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(ctor, args);
}
else {
// <x2> 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
  • <1> 如果该 bean 没有配置 lookup-methodreplaced-method 标签或者 @Lookup 注解,则直接通过反射的方式实例化 Bean 对象即可,方便快捷。
  • <2> 但是,如果存在需要覆盖的方法或者动态替换的方法时,则需要使用 CGLIB 进行动态代理,因为可以在创建代理的同时将动态方法织入类中。
反射创建 Bean 对象

调用工具类 BeanUtils 的 instantiateClass(Constructor ctor, Object... args) 方法,完成反射工作,创建对象。

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

// BeanUtils.java

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 设置构造方法,可访问
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
// 使用构造方法,创建对象
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}
// 各种异常的翻译,最终统一抛出 BeanInstantiationException 异常
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
CGLIB 创建 Bean 对象
1
2
3
4
5
// SimpleInstantiationStrategy.java

protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}

方法默认是没有实现的,具体过程由其子类 org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy 来实现。

1
2
3
4
5
6
7
8
9
10
11
12
// CglibSubclassingInstantiationStrategy.java

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
// 通过CGLIB生成一个子类对象
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
  • 创建一个 CglibSubclassCreator 对象,后调用其 instantiate(Constructor ctor, Object... args) 方法,生成其子类对象。

    注:CglibSubclassCreator是个内部类。

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
// CglibSubclassingInstantiationStrategy.java

public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
// 通过 Cglib 创建一个代理类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
// 没有构造器,通过 BeanUtils 使用默认构造器创建一个bean实例
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
} else {
try {
// 获取代理类对应的构造器对象,并实例化 bean
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
} catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
// 为了避免 memory leaks 异常,直接在 bean 实例上设置回调对象
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}

instantiateBean()方法

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
// AbstractAutowireCapableBeanFactory.java

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
// 安全模式
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
// 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
} else {
// 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 封装 BeanWrapperImpl 并完成初始化
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
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
29
30
31
32
33
34
35
36
37
38
39
40
// SimpleInstantiationStrategy.java

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获得构造方法 constructorToUse
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
// 如果是接口,抛出 BeanInstantiationException 异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 从 clazz 中,获得构造方法
if (System.getSecurityManager() != null) { // 安全模式
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
} else {
constructorToUse = clazz.getDeclaredConstructor();
}
// 标记 resolvedConstructorOrFactoryMethod 属性
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(constructorToUse);
} else {
// Must generate CGLIB subclass.
// 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

总结

对于 createBeanInstance(...) 方法而言,他就是选择合适实例化策略来为 bean 创建实例对象,具体的策略有:

  • Supplier 回调方式
  • 工厂方法初始化
  • 构造函数自动注入初始化
  • 默认构造函数注入。

其中,工厂方法初始化和构造函数自动注入初始化两种方式最为复杂,主要是因为构造函数和构造参数的不确定性,Spring 需要花大量的精力来确定构造函数和构造参数,如果确定了则好办,直接选择实例化策略即可。

当然,在实例化的时候会根据是否有需要覆盖或者动态替换掉的方法,因为存在覆盖或者织入的话需要创建动态代理将方法织入,这个时候就只能选择 CGLIB 的方式来实例化,否则直接利用反射的方式即可,方便快捷。


二十二、创建Bean之实例化Bean对象二
http://www.muzili.ren/2022/06/11/创建Bean之实例化Bean对象2/
作者
jievhaha
发布于
2022年6月11日
许可协议