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

SpringIOC-有参构造方法实例化

前言

​ 接着 Spring IoC:getBean详解,我们继续解析获取 bean 实例里的核心内容:创建 bean 实例。

autowireConstructor

通过有@Autowire注解的构造器的构造方法进行实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* 有 autowire注解的 构造器的实例化
*/
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
//通过有@Autowire注解的构造器的构造方法进行实例化
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

autowireConstructor

通过有@Autowire注解的构造器的构造方法进行实例化

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
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* <p>
* 构造方法进行实例化
*
*/
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

// 定义bean包装类
BeanWrapperImpl bw = new BeanWrapperImpl();
//忽略可以不看,设置类型转换器,注册自定义编辑器
this.beanFactory.initBeanWrapper(bw);

// 最终用于实例化的构造函数
Constructor<?> constructorToUse = null;
// 最终用于实例化的参数Holder
ArgumentsHolder argsHolderToUse = null;
// 最终用于实例化的构造函数参数
Object[] argsToUse = null;

// 1.解析出要用于实例化的构造函数参数
if (explicitArgs != null) {
// 1.1 如果explicitArgs不为空,则构造函数的参数直接使用explicitArgs
// 通过getBean方法调用时,显示指定了参数,则explicitArgs就不为null
argsToUse = explicitArgs;
} else {
// 1.2 尝试从缓存中获取已经解析过的构造函数参数
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 1.2.1 拿到缓存中已解析的构造函数或工厂方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 1.2.2 如果constructorToUse不为空 && mbd标记了构造函数参数已解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 1.2.3 从缓存中获取已解析的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 1.2.4 如果resolvedConstructorArguments为空,则从缓存中获取准备用于解析的构造函数参数,
// constructorArgumentsResolved为true时,resolvedConstructorArguments和
// preparedConstructorArguments必然有一个缓存了构造函数的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 1.2.5 如果argsToResolve不为空,则对构造函数参数进行解析,
// 如给定方法的构造函数 A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}

//如果构造函数没有被缓存
if (constructorToUse == null || argsToUse == null) {
// 2.确认构造函数的候选者
// Take specified constructors, if any.

// 2.1 如果入参chosenCtors不为空,则将chosenCtors的构造函数作为候选者
Constructor<?>[] candidates = chosenCtors;
//如果传过来的没有构造函数
if (candidates == null) {
//获取BeanClass
Class<?> beanClass = mbd.getBeanClass();
try {
// 2.2 如果入参chosenCtors为空,则获取beanClass的构造函数
// (mbd是否允许访问非公共构造函数和方法 ? 所有声明的构造函数:公共构造函数)
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);
}
}

//mbd.hasConstructorArgumentValues()这个是false的,因为是@Autowired的构造函数,不是<constructor-arg>标签
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;
}
}
//3. 通过配置文件获取
//需要解析参数
// 3.1 检查是否需要自动装配:chosenCtors不为空 || autowireMode为AUTOWIRE_CONSTRUCTOR
// 例子:当chosenCtors不为空时,代表有构造函数通过@Autowire修饰,因此需要自动装配
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;

// 构造函数参数个数
int minNrOfArgs;
if (explicitArgs != null) {
// 3.2 explicitArgs不为空,则使用explicitArgs的length作为minNrOfArgs的值
minNrOfArgs = explicitArgs.length;
} else {
// 3.3 获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值)
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 3.4 创建ConstructorArgumentValues对象resolvedValues,用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 3.5 解析mbd的构造函数的参数,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
// 注:这边解析mbd中的构造函数参数值,主要是处理我们通过xml方式定义的构造函数注入的参数,
// 但是如果我们是通过@Autowire注解直接修饰构造函数,则mbd是没有这些参数值的
}

// 3.6 对给定的构造函数排序:先按方法修饰符排序:public排非public前面,再按构造函数参数个数排序:参数多的排前面
AutowireUtils.sortConstructors(candidates);
// 最小匹配权重,权重越小,越接近我们要找的目标构造函数
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;

// 4.遍历所有构造函数候选者,找出符合条件的构造函数
for (Constructor<?> candidate : candidates) {
//4.1 获取到构造函数参数的数量
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.
// 4.2 如果已经找到满足的构造函数 && 目标构造函数需要的参数个数大于当前遍历的构造函数的参数个数则终止,
// 因为遍历的构造函数已经排过序,后面不会有更合适的候选者了
break;
}
if (parameterCount < minNrOfArgs) {
// 4.3 如果当前遍历到的构造函数的参数个数小于我们所需的参数个数,则直接跳过该构造函数
continue;
}

ArgumentsHolder argsHolder;
// 4.4 拿到当前遍历的构造函数的参数类型数组
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
// 存在参数则根据参数值来匹配参数类型
try {
// 4.5 resolvedValues不为空,
// 4.5.1 获取当前遍历的构造函数的参数名称
// 4.5.1.1 解析使用ConstructorProperties注解的构造函数参数
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
// 4.5.1.2 获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 4.5.1.3 使用参数名称解析器获取当前遍历的构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 4.5.2 创建一个参数数组以调用构造函数或工厂方法,
// 主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
//获取到参数的值,建议不要看,比较深,主流程弄懂后再去细细打磨
//获取构造参数并实例化参数
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
} catch (UnsatisfiedDependencyException ex) {
// 4.5.3 参数匹配失败,则抛出异常
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 {
// 4.6 resolvedValues为空,则explicitArgs不为空,即给出了显式参数
// Explicit arguments given -> arguments length must match exactly.
// 4.6.1 如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数
if (parameterCount != explicitArgs.length) {
continue;
}
// 4.6.2 使用显式给出的参数构造ArgumentsHolder
argsHolder = new ArgumentsHolder(explicitArgs);
}

// 4.7 根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),
// 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 4.8 类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数
if (typeDiffWeight < minTypeDiffWeight) {
// 将要使用的参数都替换成差异权重值更小的
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
// 如果出现权重值更小的候选者,则将ambiguousConstructors清空,允许之前存在权重值相同的候选者
ambiguousConstructors = null;
}
// 4.9 如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 将这两个候选者都添加到ambiguousConstructors
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}

// 5.如果最终没有找到匹配的构造函数,则进行异常处理
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()) {
// 6.如果找到了匹配的构造函数,但是存在多个(ambiguousConstructors不为空) && 解析构造函数的模式为严格模式,则抛出异常
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) {
// 7.将解析的构造函数和参数放到缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}

Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 8.根据实例化策略以及得到的构造函数及构造函数参数实例化bean
//并将构造的实例加入BeanWrapper中,并返回
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}

resolveConstructorArguments

构造方法参数解析

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
/**
* Resolve the constructor arguments for this bean into the resolvedValues object.
* This may involve looking up other beans.
* <p>This method is also used for handling invocations of static factory methods.
* <p>
* 构造方法参数解析
*/
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 1.构建bean定义值解析器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);

// 2.minNrOfArgs初始化为indexedArgumentValues和genericArgumentValues的的参数个数总和
int minNrOfArgs = cargs.getArgumentCount();

// 3.遍历解析带index的参数值
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
// index从0开始,不允许小于0
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid constructor argument index: " + index);
}
// 3.1 如果index大于minNrOfArgs,则修改minNrOfArgs
if (index > minNrOfArgs) {
// index是从0开始,并且是有序递增的,所以当有参数的index=5时,代表该方法至少有6个参数
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 3.2 解析参数值
if (valueHolder.isConverted()) {
// 3.2.1 如果参数值已经转换过,则直接将index和valueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, valueHolder);
} else {
// 3.2.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 3.2.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 3.2.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 3.2.5 将index和新的ValueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}

// 4.遍历解析通用参数值(不带index)
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
if (valueHolder.isConverted()) {
// 4.1 如果参数值已经转换过,则直接将valueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(valueHolder);
} else {
// 4.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 4.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
resolvedValue, valueHolder.getType(), valueHolder.getName());
// 4.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 4.5 将新的ValueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
// 5.返回构造函数参数的个数
return minNrOfArgs;
}

createArgumentArray

创建参数数组以调用构造函数或工厂方法,给定解析的构造函数参数值。

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
/**
* Create an array of arguments to invoke a constructor or factory method,
* given the resolved constructor argument values.
* 创建参数数组以调用构造函数或工厂方法,
* 给定解析的构造函数参数值。
*/
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {

TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
// 获取类型转换器
TypeConverter converter = (customConverter != null ? customConverter : bw);

// 新建一个ArgumentsHolder来存放匹配到的参数
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

// 1.遍历参数类型数组
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
// 拿到当前遍历的参数类型
Class<?> paramType = paramTypes[paramIndex];
// 拿到当前遍历的参数名
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
// 2.查找当前遍历的参数,是否在mdb对应的bean的构造函数参数中存在index、类型和名称匹配的
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
// 3.如果我们找不到直接匹配并且不应该自动装配,那么让我们尝试下一个通用的无类型参数值作为降级方法:它可以在类型转换后匹配(例如,String - > int)。
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// 4.valueHolder不为空,存在匹配的参数
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
// 将valueHolder添加到usedValueHolders
usedValueHolders.add(valueHolder);
// 原始属性值
Object originalValue = valueHolder.getValue();
// 转换后的属性值
Object convertedValue;
if (valueHolder.isConverted()) {
// 4.1 如果valueHolder已经转换过
// 4.1.1 则直接获取转换后的值
convertedValue = valueHolder.getConvertedValue();
// 4.1.2 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = convertedValue;
} else {
// 4.2 如果valueHolder还未转换过
// 4.2.1 将方法(此处为构造函数)和参数索引封装成MethodParameter(MethodParameter是封装方法和参数索引的工具类)
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
// 4.2.2 将原始值转换为paramType类型的值(如果类型无法转,抛出TypeMismatchException)
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
} catch (TypeMismatchException ex) {
// 4.2.3 如果类型转换失败,则抛出异常
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
// 4.2.4 拿到原始参数值
Object sourceHolder = valueHolder.getSource();
// 4.2.5 如果sourceHolder是ConstructorArgumentValues.ValueHolder类型的拿到原始的ValueHolder
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
// 4.2.6 args标记为需要解析
args.resolveNecessary = true;
// 4.2.7 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = sourceValue;
}
}
// 4.3 将convertedValue作为args在paramIndex位置的参数
args.arguments[paramIndex] = convertedValue;
// 4.4 将originalValue作为args在paramIndex位置的原始参数
args.rawArguments[paramIndex] = originalValue;
} else {
// 5.valueHolder为空,不存在匹配的参数
// 5.1 将方法(此处为构造函数)和参数索引封装成MethodParameter
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
// 5.2 找不到明确的匹配,并且不是自动装配,则抛出异常
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
// 5.3 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象
// 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
// 5.4 将通过自动装配解析出来的参数赋值给args
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
} catch (BeansException ex) {
// 5.5 如果自动装配解析失败,则会抛出异常
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
// 6.如果依赖了其他的bean,则注册依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}

return args;
}

如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的 bean 实例对象

resolveAutowiredArgument

用于解析应自动连接的指定参数的模板方法

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
/**
* Template method for resolving the specified argument which is supposed to be autowired.
* 用于解析应自动连接的指定参数的模板方法。
*/
@Nullable
protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
@Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
// 1.如果参数类型为InjectionPoint
Class<?> paramType = param.getParameterType();
if (InjectionPoint.class.isAssignableFrom(paramType)) {
// 1.1 拿到当前的InjectionPoint(存储了当前正在解析依赖的方法参数信息,DependencyDescriptor)
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
// 1.2 当前injectionPoint为空,则抛出异常:目前没有可用的InjectionPoint
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
// 1.3 返回当前的InjectionPoint
return injectionPoint;
}
try {
// 2.解析指定依赖,DependencyDescriptor:将MethodParameter的方法参数索引信息封装成DependencyDescriptor
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
} catch (NoUniqueBeanDefinitionException ex) {
throw ex;
} catch (NoSuchBeanDefinitionException ex) {
if (fallback) {
// Single constructor or factory method -> let's return an empty array/collection
// for e.g. a vararg or a non-null List/Set/Map parameter.
if (paramType.isArray()) {
return Array.newInstance(paramType.getComponentType(), 0);
} else if (CollectionFactory.isApproximableCollectionType(paramType)) {
return CollectionFactory.createCollection(paramType, 0);
} else if (CollectionFactory.isApproximableMapType(paramType)) {
return CollectionFactory.createMap(paramType, 0);
}
}
throw ex;
}
}

解析指定依赖,这边的 DependencyDescriptor 主要是封装了依赖的方法和参数的信息

resolveDependency

获取依赖对象

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
/**
* 获取依赖对象
*/
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
// 1.javaUtilOptionalClass类注入的特殊处理
return createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
// 2.ObjectFactory类注入的特殊处理
return new DependencyObjectProvider(descriptor, requestingBeanName);
} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// 3.javaxInjectProviderClass类注入的特殊处理
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
} else {
// 4.通用类注入的处理
// 4.1 如有必要,请获取延迟解析代理
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 4.2 解析依赖关系,返回的result为创建好的依赖对象的bean实例
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}

解析依赖关系,返回的 result 为创建好的依赖对象的 bean 实例

doResolveDependency

开始获取赖对象

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
/**
* 获取依赖对象
*/
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//1.设置当前的descriptor(存储了方法参数等信息)为当前注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 2.如果是ShortcutDependencyDescriptor,则直接通过getBean方法获取Bean实例,并返回;否则返回null
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 3.拿到descriptor包装的方法的参数类型(通过参数索引定位到具体的参数)
Class<?> type = descriptor.getDependencyType();
// 4.用于支持spring中新增的注解@Value(确定给定的依赖项是否声明Value注解,如果有则拿到值)
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}

TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
} catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
// 4.1 如果使用了@Value注解,则将解析到的值转换成所需的类型并返回
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 5.解析MultipleBean(下文的MultipleBean都是指类型为:Array、Collection、Map)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
// 5.1 如果确实是容器类型的属性,则直接返回解析结果
return multipleBeans;
}
// 6.查找与所需类型匹配的Bean实例(matchingBeans,key:beanName;value:匹配的bean实例,或者匹配的bean实例的类型)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 6.1 如果require属性为true,而找到的匹配Bean却为空则抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
// 6.2 如果require属性为false,而找到的匹配Bean却为空,则返回nul
return null;
}

String autowiredBeanName;
Object instanceCandidate;

if (matchingBeans.size() > 1) {
// 7.非MultipleBean,但是有多个候选者
// 7.1 从多个候选者中选出最优的那个
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
} else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
// 7.2.拿到autowiredBeanName对应的value(bean实例或bean实例类型)
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
// 8.只找到了一个候选者,则直接使用该候选者
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}

if (autowiredBeanNames != null) {
// 9.将依赖的beanName加到autowiredBeanNames中
autowiredBeanNames.add(autowiredBeanName);
}
// 10.如果instanceCandidate为Class,则instanceCandidate为bean实例的类型,执行descriptor.resolveCandidate方法,
// 通过getBean方法获取bean实例并返回;如果instanceCandidate不是Class,则instanceCandidate为bean实例,直接返回该实例
//如果是引用类型
if (instanceCandidate instanceof Class) {
//获取依赖bean的实例
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
} finally {
// 11.执行结束,将注入点修改成原来的注入点
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}

​ 如果是 ShortcutDependencyDescriptor,则直接通过 getBean 方法获取 bean 实例,并返回;否则返回 null。

​ 通过构造函数注入依赖的 bean 实例的整个过程是不会出现涉及到 ShortcutDependencyDescriptor 的。ShortcutDependencyDescriptor 主要用于 @Autowire 注解,在解析 @Autowire 注解的时候,当第一次注入依赖的 bean 实例后,会将该依赖的 bean 的信息封装成 ShortcutDependencyDescriptor ,放到缓存中去,下一次需要依赖注入该 bean 时,可以直接快速的拿到该 bean 实例。
​ 查找与所需类型匹配的 bean 实例,这边的返回结果 matchingBeans 的 key 是 beanName,而 value 有两种情况:一种是匹配的 bean 实例,另一种是匹配的 bean 实例的类型

从多个候选者中选出最优的那个

查找依赖关系

findAutowireCandidates

查找与所需类型匹配的bean实例。在为指定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
/**
* Find bean instances that match the required type.
* Called during autowiring for the specified bean.
* 查找与所需类型匹配的bean实例。在为指定bean自动连接期间调用。
*/
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

// 1.获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 2.首先从已经解析的依赖关系缓存中寻找是否存在我们想要的类型
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// 2.1 autowiringType是否与requiredType相同,或者是requiredType的超类、超接口
if (autowiringType.isAssignableFrom(requiredType)) {
// 2.2 如果requiredType匹配,则从缓存中拿到相应的自动装配值(bean实例)
Object autowiringValue = classObjectEntry.getValue();
// 2.3 根据给定的所需类型解析给定的自动装配值
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
// 2.4 将autowiringValue放到结果集中,此时的value为bean实例
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 3.遍历从容器中获取到的类型符合的beanName
for (String candidate : candidateNames) {
// isAutowireCandidate:判断是否有资格作为依赖注入的候选者
// 3.1 如果不是自引用 && candidate有资格作为依赖注入的候选者
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 3.2 将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 4.如果结果为空 && type不是MultipleBean(Array、Collection、Map),则使用降级匹配
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
// 4.1 使用降级匹配(跟正常匹配类似)
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
// 5.如果使用降级匹配结果还是空,则考虑自引用
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
// 5.1 如果是自引用 && (descriptor不是MultiElementDescriptor || beanName不等于候选者)
// && candidate允许依赖注入,则将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
// 6.返回符合条件的候选者
return result;
}

isAutowireCandidate:判断是否有资格作为依赖注入的候选者

isAutowireCandidate

解析beanName对应的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
/**
* 解析beanName对应的bean是否有资格作为候选者
* @param beanName
* @param descriptor
* @return
* @throws NoSuchBeanDefinitionException
*/
@Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
// getAutowireCandidateResolver: 返回BeanFactory的@Autowire解析器,开启注解后的解析器为:ContextAnnotationAutowireCandidateResolver
// 解析beanName对应的bean是否有资格作为候选者
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}

/**
* Determine whether the specified bean definition qualifies as an autowire candidate,
* to be injected into other beans which declare a dependency of matching type.
* 解析beanName对应的bean是否有资格作为候选者
*/
protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
throws NoSuchBeanDefinitionException {
// 1.解析beanName,去掉FactoryBean的修饰符“&”
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(beanDefinitionName)) {
// 2.beanDefinitionMap缓存中存在beanDefinitionName:通过beanDefinitionName缓存拿到MergedBeanDefinition,
// 将MergedBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
} else if (containsSingleton(beanName)) {
// 3.singletonObjects缓存中存在beanName:使用beanName构建RootBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}

// 4.在beanDefinitionMap缓存和singletonObjects缓存中都不存在,则在parentBeanFactory中递归解析beanName是否有资格作为候选者
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
} else if (parent instanceof ConfigurableListableBeanFactory) {
// If no DefaultListableBeanFactory, can't pass the resolver along.
return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
} else {
return true;
}
}
isAutowireCandidate

继续解析 beanName 是否有资格作为候选者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Determine whether the specified bean definition qualifies as an autowire candidate,
* to be injected into other beans which declare a dependency of matching type.
* 继续解析 beanName 是否有资格作为候选者
*/
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {

// 1.解析beanName,去掉FactoryBean的修饰符“&”
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
// 2.解析mbd的beanClass
resolveBeanClass(mbd, beanDefinitionName);
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
// 3.如果缓存中已经存在解析的构造函数或工厂方法,则解析mbd中的工厂方法,并替换掉缓存中的方法
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
// 4.使用resolver解析器解析mbd是否有资格作为依赖注入的候选者
return resolver.isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
isAutowireCandidate

使用resolver解析器解析mbd是否有资格作为依赖注入的候选者

1
2
3
4
5
6
7
8
9
10
/**
* Determine whether the given bean definition qualifies as an
* autowire candidate for the given dependency.
* <p>The default implementation checks
* 获取此bean是否可以自动注入到其他bean(autowireCandidate属性),默认为true,一般不修改,因此这边返回true
*/
default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 获取此bean是否可以自动注入到其他bean(autowireCandidate属性),默认为true,一般不修改,因此这边返回true
return bdHolder.getBeanDefinition().isAutowireCandidate();
}

addCandidateEntry

添加将候者

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
/**
* Add an entry to the candidate map: a bean instance if available or just the resolved
* type, preventing early bean initialization ahead of primary candidate selection.
* 添加将候者
*/
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 1.如果descriptor为MultiElementDescriptor类型 || candidateName已经在singletonObjects缓存中存在
if (descriptor instanceof MultiElementDescriptor) {
// 2.1 resolveCandidate: 通过candidateName获取对应的bean实例
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
//如果实例不是NullBean
if (!(beanInstance instanceof NullBean)) {
// 2.2 将beanName -> bean实例 的映射添加到candidates(此时的value为bean实例)
candidates.put(candidateName, beanInstance);
}
} else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
} else {
// 3.将beanName -> bean实例的类型 的映射添加到candidates(此时的value为bean实例的类型)
candidates.put(candidateName, getType(candidateName));
}
}

​ 当被依赖注入的属性是 MultipleBean(Array、Collection、Map)类型,生成的依赖描述类型是 MultiElementDescriptor,因此所有的候选者均是合格的,所以会当场实例化他们(2.1)。而如果属性的类型是非 MultipleBean,那么可能是从多个候选者中挑一个最合适的,因此此时实例化他们就不合适了,最终会把最合适的那个实例化,如果没有合格的则不应该实例化。

determineAutowireCandidate
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
/**
* Determine the autowire candidate in the given set of beans.
* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
* 确定给定bean集中的autowire候选者的优先级
*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
//获取依赖类型
Class<?> requiredType = descriptor.getDependencyType();
// 1.根据@Primary注解来选择最优解
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 2.根据@Priority注解来选择最优解
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 3.如果通过以上两步都不能选择出最优解,则使用最基本的策略
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// 3.1 containsValue:首先如果这个beanInstance已经由Spring注册过依赖关系,则直接使用该beanInstance作为最优解,
// 3.2 matchesBeanName:如果没有注册过此beanInstance的依赖关系,则根据参数名称来匹配,
// 如果参数名称和某个候选者的beanName或别名一致,那么直接将此bean作为最优解
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
// 4.没有找到匹配的候选者,则返回null
return null;
}

protected boolean matchesBeanName(String beanName, @Nullable String candidateName) {
// candidateName与beanName相等 || beanName有别名与candidateName相等,则返回true
return (candidateName != null &&
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
}

1.根据 @Primary 注解来选择最优解

2.根据 @Priority 注解来选择最优解

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
/**
* Determine the primary candidate in the given set of beans.
* 使用@Primary注解 确定候选者
*/
@Nullable
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String primaryBeanName = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 2.判断候选者bean是否使用了@Primary注解:如果candidateBeanName在当前BeanFactory中存在BeanDefinition,
// 则判断当前BeanFactory中的BeanDefinition是否使用@Primary修饰;否则,在parentBeanFactory中判断
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
// 3.走到这边primaryBeanName不为null,代表标识了@Primary的候选者不止一个,则判断BeanName是否存在于当前BeanFactory
// candidateLocal:candidateBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
// primaryLocal:primaryBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal && primaryLocal) {
// 3.1 如果当前BeanFactory中同一个类型的多个Bean,不止一个Bean使用@Primary注解,则抛出异常
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
} else if (candidateLocal) {
// 3.2 candidateLocal为true,primaryLocal为false,则代表primaryBeanName是parentBeanFactory中的Bean,
// candidateBeanName是当前BeanFactory中的Bean,当存在两个都使用@Primary注解的Bean,优先使用当前BeanFactory中的
primaryBeanName = candidateBeanName;
}
// 3.3 candidateLocal为false,primaryLocal为true,则代表primaryBeanName是当前BeanFactory中的Bean,
// candidateBeanName是parentBeanFactory中的Bean,因此无需修改primaryBeanName的值
} else {
// 4.primaryBeanName还为空,代表是第一个符合的候选者,直接将primaryBeanName赋值为candidateBeanName
primaryBeanName = candidateBeanName;
}
}
}
// 5.返回唯一的使用@Primary注解的Bean的beanName(如果都没使用@Primary注解则返回null)
return primaryBeanName;
}
determineHighestPriorityCandidate
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
/**
* Determine the candidate with the highest priority in the given set of beans. * <p>Based on {@code @javax.annotation.Priority}. As defined by the related
* {@link org.springframework.core.Ordered} interface, the lowest value has
* the highest priority.
* Priority注解 候选者选择
*/
@Nullable
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
// 用来保存最高优先级的beanName
String highestPriorityBeanName = null;
// 用来保存最高优先级的优先级值
Integer highestPriority = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (beanInstance != null) {
// 2.拿到beanInstance的优先级
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (highestPriorityBeanName != null) {
// 3.如果之前已经有候选者有优先级,则进行选择
if (candidatePriority.equals(highestPriority)) {
// 3.1 如果存在两个优先级相同的Bean,则抛出异常
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"Multiple beans found with the same priority ('" + highestPriority +
"') among candidates: " + candidates.keySet());
} else if (candidatePriority < highestPriority) {
// 3.2 使用优先级值较小的Bean作为最优解(值越低,优先级越高)
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
} else {
// 4.第一次有候选者有优先级
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
}
}
// 5.返回优先级最高的bean的beanName
return highestPriorityBeanName;
}

评论