使用工厂方法获取新实例的BeanWrapper,使用命名的工厂方法实例化bean。如果mbd参数指定了一个类,而不是factoryBean,或者在使用依赖项注入配置的工厂对象本身上指定了一个实例变量,那么该方法可能是静态的。

1
2
3
4
5
6
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//首先为给定的工厂和实例化策略创建一个新的构造解析器。
//之后调用instantiateUsingFactoryMethod,使用命名的工厂方法实例化bean。
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

下面分析ConstructorResolver类中的instantiateUsingFactoryMethod方法,吐槽:这块代码写的太乱了!应该再分割一下的,太长了看着吃力,没办法,硬看吧:

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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/**
* 使用命名的工厂方法实例化bean。
* 如果bean定义参数指定了一个类,而不是“factory-bean”或
* 使用依赖项注入配置的工厂对象本身的实例变量,则该方法可能是静态的。
* 实现需要使用RootBeanDefinition中指定的名称遍历静态方法或实例方法(方法可能被重载),并尝试与参数匹配。
* 我们没有附加到构造函数args的类型,所以尝试和错误是唯一的方法。
* explicitArgs数组可以包含通过相应的getBean方法以编程方式传入的参数值。
*
* @param beanName bean的名称
* @param mbd bean的合并bean定义
* @param explicitArgs 参数值通过getBean方法以编程方式传入,如果没有参数值,则为{@code null}(->使用bean定义中的构造函数参数值)
* @return 新实例的BeanWrapper
*/
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//--BeanWrapper部分

//首先组装BeanWrapperImpl,为啥不用BeanWrapper接口,是因为方法后面有调用定制化方法
BeanWrapperImpl bw = new BeanWrapperImpl();
//初始化BeanWrapper
this.beanFactory.initBeanWrapper(bw);


//---factoryBean部分
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;

//返回工厂bean名称。
String factoryBeanName = mbd.getFactoryBeanName();
//如果有的话
if (factoryBeanName != null) {
//工厂bean引用指向相同的bean定义
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
//从工厂中获取factoryBean
factoryBean = this.beanFactory.getBean(factoryBeanName);
//如果是单例模式,返回隐式出现单例异常
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
//factoryClass
factoryClass = factoryBean.getClass();
isStatic = false;
}
//如果没有工厂bean名称
else {
// 工厂名为空,则其可能是一个静态工厂
if (!mbd.hasBeanClass()) {
//bean定义既没有声明bean类,也没有声明工厂bean引用
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}

//---构造参数解析部分

//工厂方法
Method factoryMethodToUse = null;
//用于保存参数组合
ArgumentsHolder argsHolderToUse = null;
//参数
Object[] argsToUse = null;

if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
Object[] argsToResolve = null;
//constructorArgumentLock为RootBeanDefinition中构造函数的公共锁
synchronized (mbd.constructorArgumentLock) {
//构造函数或工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
//constructorArgumentsResolved字段将构造函数参数标记为已解析
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// 找到一个缓存的工厂方法…
// 完全解析的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//部分准备好的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//preparedConstructorArguments中存在值
if (argsToResolve != null) {
// 解析存储在给定bean定义中的准备好的参数。
// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
// 缓存中的值可能是原始值也有可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}

//---工厂方法部分

if (factoryMethodToUse == null || argsToUse == null) {
// 需要确定工厂的方法…
// 尝试所有具有此名称的方法,看看它们是否匹配给定的参数。
// 为给定的类返回用户定义的类:通常只是给定的类,但如果是cglib生成的子类,则返回原始类。
// CGLIB类分隔符:{@code "$$"}。
factoryClass = ClassUtils.getUserClass(factoryClass);

//给定类的所有候选方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
//方法处理
List<Method> candidateList = new ArrayList<>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidateList.add(candidate);
}
}

//如果构造方法只有一个,且参数为空,mbd也没有参数
if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidateList.get(0);
//如果方法参数为0
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
//instantiate方法获取对象实例,比较重要,稍后单独分析
//设置要保存的bean实例
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}

Method[] candidates = candidateList.toArray(new Method[0]);
//排序给定的工厂方法,选择公共方法和参数最多的“贪婪”方法。
// 结果将首先包含公共方法,减少参数的数量,然后是非公共方法,再次减少参数的数量。
AutowireUtils.sortFactoryMethods(candidates);

// 用于承载解析后的构造函数参数的值
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;

int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
// 我们没有以编程方式传入参数,
// 因此需要解析bean定义中包含的构造函数参数中指定的参数。
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//构造方法参数解析
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} else {
minNrOfArgs = 0;
}
}

LinkedList<UnsatisfiedDependencyException> causes = null;

for (Method candidate : candidates) {
//方法体的参数
Class<?>[] paramTypes = candidate.getParameterTypes();

if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;

//如果有明确的参数
if (explicitArgs != null) {
// 给定显式参数->参数长度必须精确匹配。
if (paramTypes.length != explicitArgs.length) {
continue;
}
//封装参数持有者
argsHolder = new ArgumentsHolder(explicitArgs);
}
//如果没有明确的参数
else {
//解析构造函数参数:类型转换和/或必要的自动装配。
try {
String[] paramNames = null;
//ParameterNameDiscoverer:解析方法参数名
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//解析方法参数名
paramNames = pnd.getParameterNames(candidate);
}
//给定已解析的构造函数参数值,创建一个参数数组来调用构造函数或工厂方法。
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
} catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}

//返回在宽松模式下解析构造函数还是在严格模式下解析构造函数。
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果工厂方法表示最接近的匹配,则选择该方法
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项
// 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名)
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {

// 查找到多个可匹配的方法
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}

// 没有可执行的工厂方法,抛出异常
if (factoryMethodToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
} else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
} else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
} else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}

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

Assert.state(argsToUse != null, "Unresolved factory method arguments");
//通过执行工厂方法来创建bean示例
//设置要保存的bean实例
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}

简单的梳理一下流程:

  • 组装BeanWrapperImpl,这里没用接口编程是因为后面有定制其定制化方法。
  • 组装factoryBean,如果工厂名不为空,通过beanFactory.getBean()获取工厂对象,如果为空,则可能是静态工厂。
  • 构造参数解析:明确指定参数;从缓存中获取参数;BeanDifinition中的参数
  • 构造方法解析,各种解析最后构造方法确认好
  • 将解析的构造方法加入缓存
  • 调用instantiate方法获取对象实例,这里是通过java反射获取的对象。

1、instantiate

首先,beanFactory获取获取实例化策略,这里使用的是SimpleInstantiationStrategy,之后通过java反射,获取对象。

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
//实例化方法
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {

//首先获取实例化策略getInstantiationStrategy,默认CGLIB策略
//如果需要容器覆盖方法来实现方法注入,则使用CGLIB动态生成子类。
//之后调用instantiate,获取对象
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);
}
}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {

try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
}
else {
ReflectionUtils.makeAccessible(factoryMethod);
}

Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {
result = new NullBean();
}
return result;
}
finally {
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod,
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod,
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
}
catch (InvocationTargetException ex) {
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
"declaring the factory method as static for independence from its containing instance. " + msg;
}
throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
}
}

tencent.jpg