本篇分析AbstractAutowireCapableBeanFactory中的autowireConstructor方式获取新实例的BeanWrapper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* “自动装配构造函数”(按类型提供构造函数参数)行为。
* 如果指定了显式构造函数参数值,
* 还可以使用bean工厂中的bean匹配所有剩余的参数。
* 这对应于构造函数注入:
* 在这种模式下,Spring bean工厂能够承载期望基于构造函数的依赖项解析的组件。
*
* @param beanName bean的名称
* @param mbd bean的bean定义
* @param ctors 选择的候选构造函数
* @param explicitArgs 参数值通过getBean方法以编程方式传入,如果没有参数值,
* 则为{@code null}(->使用bean定义中的构造函数参数值)
* @return 新实例的BeanWrapper
*/
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
//首先为给定的工厂和实例化策略创建一个新的构造解析器。
//之后调用ConstructorResolver类的autowireConstructor方法获取新实例的BeanWrapper
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

这个方法在AbstractAutowireCapableBeanFactory的方法createBeanInstance中有三处调用:

1
2
3
autowireConstructor(beanName, mbd, null, null)
autowireConstructor(beanName, mbd, ctors, args)
autowireConstructor(beanName, mbd, ctors, null)

即可以指定构造函数和参数值。
下面主要分析ConstructorResolver中的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
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
/**
* “自动装配构造函数”(按类型提供构造函数参数)行为。
* 如果指定了显式构造函数参数值,还可以使用bean工厂中的bean匹配所有剩余的参数。
* 这对应于构造函数注入:在这种模式下,Spring bean工厂能够承载期望基于构造函数的依赖项解析的组件。
*
* @param beanName bean的名称
* @param mbd bean的bean定义
* @param chosenCtors 选择的候选构造函数
* @param explicitArgs 参数值通过getBean方法以编程方式传入,如果没有参数值,
* 则为{@code null}(->使用bean定义中的构造函数参数值)
* @return 新实例的BeanWrapper
*/
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

//---组装BeanWrapper
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;

//---构造参数处理
//指定了参数值,则argsToUse为explicitArgs
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 中的参数
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}

//--缓存中没有,则尝试从配置文件中获取
if (constructorToUse == null || argsToUse == null) {
// 使用指定的构造函数(如果有的话)。
Constructor<?>[] candidates = chosenCtors;
//如果没有指定构造参数
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//是否允许访问非公共构造函数和方法
//getDeclaredConstructors返回所有构造函数对象数组
//getConstructors只返回public构造
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);
}
}

//无参构造解析
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;
}
}

// 需要解析构造函数。
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
//构造函数参数值
ConstructorArgumentValues resolvedValues = null;

int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//将此bean的构造函数参数解析为resolvedValues对象。
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

//public 构造函数优先参数数量降序,
//非public 构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
//最小参数权重
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;

//迭代所有构造函数
for (Constructor<?> candidate : candidates) {
//构造函数参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();

// 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数,则终止
// 因为已经按照参数个数降序排列了
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
//已经找到贪婪的构造函数,可以满足->不看任何进一步,只有较少的贪婪构造函数留下。
break;
}
// 参数个数不相等,继续循环
if (paramTypes.length < minNrOfArgs) {
continue;
}

//参数持有者
ArgumentsHolder argsHolder;
//构造函数参数值为null
if (resolvedValues != null) {
try {
//用于检查Java 6的{@link ConstructorProperties}注释上的参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
//解析方法参数名
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取方法参数名
paramNames = pnd.getParameterNames(candidate);
}
}
//根据构造函数和构造参数创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
} catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
} else {
// 给定显式参数->参数长度必须精确匹配。
if (paramTypes.length != explicitArgs.length) {
continue;
}
//封装参数持有者
argsHolder = new ArgumentsHolder(explicitArgs);
}

// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(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);
}
}

//如果还是没有构造函数,则抛出异常
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);
}
}

//--实例化bean
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}

简单概括一下流程:

  • 组装BeanWrapper
  • 构造参数处理
  • 构造方法处理
  • 实例化bean

1、instantiate(beanName, mbd, constructorToUse, argsToUse)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//指定了构造方法的实例化bean
private Object instantiate(
String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {

try {
//获取初始化策略,之后调用初始化方法
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
this.beanFactory.getAccessControlContext());
} else {
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}

其中strategy.instantiate方法单独拉出来分析,这里的实例化逻辑是如果存在需要覆盖的方法或者动态替换的方法则需要使用 CGLIB 进行动态代理,其余使用反射的方式。

tencent.jpg