抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Spring源码分析-工厂方式实例化

前言

​ 上一节讲了实例化的三种方式:工厂方法,构造方法以及无参的实例化,这一解我们讲一下工厂方式的实例化

instantiateUsingFactoryMethod

如果存在工厂方法,则调用 instantiateUsingFactoryMethod() 完成 bean 的初始化工作(方法实现比较长,细节比较复杂,各位就硬着头皮看吧)。

1
2
3
4
5
6
7
8
9
10
11
/**
* Instantiate the bean using a named factory method. The method may be static, if the
* mbd parameter specifies a class, rather than a factoryBean, or an instance variable
* on a factory object itself configured using Dependency Injection.
* 使用 FactoryMethod实例化bean
*/
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//创建一个工厂委托类ConstructorResolver并进行工厂的实例化
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

​ 构造一个 ConstructorResolver 对象,然后调用其 instantiateUsingFactoryMethod() 方法。ConstructorResolver 是构造方法或者工厂类初始化 bean 的委托类。

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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/**
* Instantiate the bean using a named factory method. The method may be static, if the
* bean definition parameter specifies a class, rather than a "factory-bean", or
* an instance variable on a factory object itself configured using Dependency Injection.
* <p>Implementation requires iterating over the static or instance methods with the
* name specified in the RootBeanDefinition (the method may be overloaded) and trying
* to match with the parameters. We don't have the types attached to constructor args,
* so trial and error is the only way to go here. The explicitArgs array may contain
* argument values passed in programmatically via the corresponding getBean method.
* 通过工厂委托类进行实例化bean
*
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param explicitArgs argument values passed in programmatically via the getBean
* method, or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//1. 创建BeanWrapper的实现类
BeanWrapperImpl bw = new BeanWrapperImpl();
//2. 初始化 BeanWrapperImpl
// 向BeanWrapper对象中添加 ConversionService 对象和属性编辑器 PropertyEditor 对象
this.beanFactory.initBeanWrapper(bw);

Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
//获取factoryBean的name
String factoryBeanName = mbd.getFactoryBeanName();

/**
* 如果存在factoryBeanName
* <bean class="com.xiangxue.jack.bean.PropertyClass" id="propertyClass"
* factory-bean="factoryBean" factory-method="factoryMethod"/>
*
* 需要先实例化factoryBean然后才能调用factoryMethod
*/
//3. 判断factoryBeanName不为空
if (factoryBeanName != null) {
//3.1 如果factoryBean和beanName一样直接报错
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
//4. 获取工厂bean的实例
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
//5. 获取工厂bean的class
factoryClass = factoryBean.getClass();
//说明这不是一个静态方法
isStatic = false;
} else {
/**
* 如果不存在factoryBeanName
* <bean class="com.xiangxue.jack.bean.PropertyClass" id="propertyClass"
* factory-method="factoryMethod"/>
*
* factoryMethod是一个静态方法,不需要先实例化factoryBean就可以调用factoryMethod
*/
// It's a static factory method on the bean class.
//6. 工厂名为空,则其可能是一个静态工厂
// 静态工厂创建bean,必须要提供工厂的全类名
//如果BeanDefinition没有beanClass 直接报错
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
//7. 设置静态工厂类的一下属性
//7.1 设置factoryBean为null
factoryBean = null;
//7.2 设置factoryClass为BeanDefinition的class
factoryClass = mbd.getBeanClass();
//说明这是一个静态方法
isStatic = true;
}

// 工厂方法
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 参数
Object[] argsToUse = null;

// 工厂方法的参数
// 如果指定了构造参数则直接使用
// 在调用 getBean 方法的时候指定了方法参数
if (explicitArgs != null) {
//参数赋值
argsToUse = explicitArgs;
} else {
// 没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
// 首先尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
// 获取缓存中的构造函数或者工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
// 获取缓存中的构造参数
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, factoryMethodToUse, argsToResolve, true);
}
}

if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
// 获取工厂方法的类全名称
factoryClass = ClassUtils.getUserClass(factoryClass);

List<Method> candidates = null;
// 如果工厂方法是唯一的
if (mbd.isFactoryMethodUnique) {
if (factoryMethodToUse == null) {
//将工厂方法转换成内省方法
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
if (factoryMethodToUse != null) {
//获取方法的集合
candidates = Collections.singletonList(factoryMethodToUse);
}
}
//如果candidates为null说明
if (candidates == null) {
candidates = new ArrayList<>();
// 获取所有待定方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// 检索所有方法,这里是对方法进行过滤
for (Method candidate : rawCandidates) {
// 如果有static 且为工厂方法,则添加到 candidateSet 中
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}

if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidates.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}

// 排序构造函数
// public 构造函数优先参数数量降序,非public 构造函数参数数量降序
if (candidates.size() > 1) { // explicitly skip immutable singletonList
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}

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

int minNrOfArgs;
// getBean()传递了参数
if (explicitArgs != null) {
//获取参数的长度
minNrOfArgs = explicitArgs.length;
} else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
// getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数
if (mbd.hasConstructorArgumentValues()) {
// 构造函数的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} else {
minNrOfArgs = 0;
}
}

LinkedList<UnsatisfiedDependencyException> causes = null;

for (Method candidate : candidates) {
// 方法体的参数
int parameterCount = candidate.getParameterCount();
if (parameterCount >= minNrOfArgs) {
// 保存参数的对象
ArgumentsHolder argsHolder;
//获取参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// getBean()传递了参数
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
// 显示给定参数,参数长度必须完全匹配
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 根据参数创建参数持有者
argsHolder = new ArgumentsHolder(explicitArgs);
} else {
// 为提供参数,解析构造参数
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {
String[] paramNames = null;
// 获取 ParameterNameDiscoverer 对象
// ParameterNameDiscoverer 是用于解析方法和构造函数的参数名称的接口,为参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
// 在已经解析的构造函数参数值的情况下,创建一个参数持有者对象
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.size() == 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;
}
}

// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
// 代表最接近的类型匹配,则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
// 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项
// 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名)
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 || argsToUse == 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);
}
}
//封装并实例化工厂bean
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}

instantiateUsingFactoryMethod() 方法体实在是太大了,处理细节感觉很复杂,LZ是硬着头皮看完的,中间断断续续的。吐槽这里的代码风格,完全不符合我们前面看的 Spring 代码风格。Spring 的一贯做法是将一个复杂逻辑进行拆分,分为多个细小的模块进行嵌套,每个模块负责一部分功能,模块与模块之间层层嵌套,上一层一般都是对下一层的总结和概括,这样就会使得每一层的逻辑变得清晰易懂。

​ 回归到上面的方法体,虽然代码体量大,但是总体我们还是可看清楚这个方法要做的事情。一句话概括就是:确定工厂对象,然后获取构造函数和构造参数,最后调用 InstantiationStrategy 对象的 instantiate() 来创建 bean 实例。下面我们就这个句概括的话进行拆分并详细说明。

确定工厂对象

​ 首先获取工厂方法名,若工厂方法名不为空,则调用 beanFactory.getBean() 获取工厂对象,若为空,则可能为一个静态工厂,对于静态工厂则必须提供工厂类的全类名,同时设置 factoryBean = null

构造参数确认

​ 工厂对象确定后,则是确认构造参数。构造参数的确认主要分为三种情况:explicitArgs 参数、缓存中获取、配置文件中解析。

explicitArgs 参数

​ explicitArgs 参数是我们调用 getBean() 时传递景来,一般该参数,该参数就是用于初始化 bean 时所传递的参数,如果该参数不为空,则可以确定构造函数的参数就是它了。

缓存中获取

​ 在该方法的最后,我们会发现这样一段代码:argsHolderToUse.storeCache(mbd, factoryMethodToUse) ,这段代码主要是将构造函数、构造参数保存到缓存中,如下:

storeCache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void storeCache(RootBeanDefinition mbd, Executable constructorOrFactoryMethod) {
synchronized (mbd.constructorArgumentLock) {
// 将构造函数或工厂方法放到resolvedConstructorOrFactoryMethod缓存
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// constructorArgumentsResolved标记为已解析
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {
// 如果参数需要解析,则将preparedArguments放到preparedConstructorArguments缓存
mbd.preparedConstructorArguments = this.preparedArguments;
} else {
// 如果参数不需要解析,则将arguments放到resolvedConstructorArguments缓存
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
}

​ 其中涉及到的几个参数 constructorArgumentLock、resolvedConstructorOrFactoryMethod、constructorArgumentsResolved、resolvedConstructorArguments。这些参数都是跟构造函数、构造函数缓存有关的。

  • constructorArgumentLock:构造函数的缓存锁
  • resolvedConstructorOrFactoryMethod:缓存已经解析的构造函数或者工厂方法
  • constructorArgumentsResolved:标记字段,标记构造函数、参数已经解析了。默认为false
  • resolvedConstructorArguments:缓存已经解析的构造函数参数,包可见字段

​ 如果缓存中存在构造参数,则需要调用 resolvePreparedArguments() 方法进行转换,因为缓存中的值有可能是最终值也有可能不是最终值,比如我们构造函数中的类型为 Integer 类型的 1 ,但是原始的参数类型有可能是 String 类型的 1 ,所以即便是从缓存中得到了构造参数也需要经过一番的类型转换确保参数类型完全对应。

配置文件中解析

​ 即没有通过传递参数的方式传递构造参数,缓存中也没有,那就只能通过解析配置文件获取构造参数了。

​ 在 bean 解析类的博文中我们了解了,配置文件中的信息都会转换到 BeanDefinition 实例对象中,所以配置文件中的参数可以直接通过 BeanDefinition 对象获取。代码如下:

1
2
3
4
5
6
7
8
if (mbd.hasConstructorArgumentValues()) {
// 构造函数的参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析构造函数的参数
// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

​ 通过 BeanDefinition 的 getConstructorArgumentValues() 就可以获取构造信息了,有了构造信息就可以获取相关的参数值信息了,获取的参数信息包括直接值和引用,这一步骤的处理交由 resolveConstructorArguments() 完成,该方法会将构造参数信息解析为 resolvedValues 对象 并返回解析到的参数个数。

构造函数

​ 确定构造参数后,下一步则是确定构造函数。第一步则是通过 getCandidateMethods() 获取所有的构造方法,同时对构造方法进行刷选,然后在对其进行排序处理(AutowireUtils.sortFactoryMethods(candidates)),排序的主要目的是为了能够更加方便的找到匹配的构造函数,因为构造函数的确认是根据参数个数确认的。排序的规则是:public 构造函数优先参数数量降序、非 public 构造参数数量降序。

​ 通过迭代 candidates(包含了所有要匹配的构造函数)的方式,一次比较其参数,如果显示提供了参数(explicitArgs != null),则直接比较两者是否相等,如果相等则表示找到了,否则继续比较。如果没有显示提供参数,则需要获取 ParameterNameDiscoverer 对象,该对象为参数名称探测器,主要用于发现方法和构造函数的参数名称。

​ 将参数包装成 ArgumentsHolder 对象,该对象用于保存参数,我们称之为参数持有者。当将对象包装成 ArgumentsHolder 对象后,我们就可以通过它来进行构造函数匹配,匹配分为严格模式和宽松模式。

  • 严格模式:解析构造函数时,必须所有参数都需要匹配,否则抛出异常
  • 宽松模式:使用具有”最接近的模式”进行匹配

判断的依据是根据 BeanDefinition 的 isLenientConstructorResolution 属性(该参数是我们在构造 AbstractBeanDefinition 对象是传递的)来获取类型差异权重(typeDiffWeight) 的。如果 typeDiffWeight < minTypeDiffWeight ,则代表“最接近的模式”,选择其作为构造函数,否则只有两者具有相同的参数数量且类型差异权重相等才会纳入考虑范围。

至此,构造函数已经确认了。

创建 bean 实例

工厂对象、构造函数、构造参数都已经确认了,则最后一步就是调用 InstantiationStrategy 对象的 instantiate() 来创建 bean 实例,如下:

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/**
* 实例化工厂bean
*
*/
@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>) () -> {
//设置可以factoryMethod允许访问
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
} else {
//设置可以factoryMethod允许访问
ReflectionUtils.makeAccessible(factoryMethod);
}
//从ThreadLocal中获取工厂方法
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
//将factoryMethod设置进ThreadLocal中
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());
}
}

instantiate() 最核心的部分就是利用 Java 反射执行工厂方法并返回创建好的实例,也就是这段代码:

1
Object result = factoryMethod.invoke(factoryBean, args);

到这里 instantiateUsingFactoryMethod() 已经分析完毕了。

createBeanInstance() 还有两个重要方法 autowireConstructor()instantiateBean() ,由于篇幅问题,所以将这两个方法放在下篇博客分析。

评论