Spring5源码解析四

  • instantiateBean(beanName, mbd); 使用默认构造方法实例化对象。
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
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>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
//getInstantiationStrategy()得到类的实例化策略
//默认情况下是得到一个反射的实例化策略
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

# SimpleInstantiationStrategy
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//检测 bean 配置中是否配置了 lookup-method 或 replace-method
//如果配置了就需使用 CGLIB 构建 bean 对象
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
//得到默认的无参构造方法
//constructorToUse:表示spring使用哪个构造方法实例化对象
constructorToUse = clazz.getDeclaredConstructor();
}
//记录resolvedConstructorOrFactoryMethod为默认的无参构造方法
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//调用反射技术,实例化对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 设置构造方法为可访问
ReflectionUtils.makeAccessible(ctor);
//反射创建对象 ctor.newInstance(args)
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
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());
}
}
  • autowireConstructor(beanName, mbd, ctors, 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
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
java复制代码protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//实力一个BeanWrapperImpl 对象很好理解
//前面外部返回的BeanWrapper 其实就是这个BeanWrapperImpl
//因为BeanWrapper是个接口
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

//决定要使用哪个构造方法实例化对象
Constructor<?> constructorToUse = null;

//构造方法的值,注意不是参数
//我们都知道构造方法通过反射来实例一个对象
//在调用反射来实例对象的时候,需要具体的值
//这个变量就是用来记录这些值的
//但是这里需要注意的是argsHolderToUse是一个数据结构
ArgumentsHolder argsHolderToUse = null;

//argsToUse[]才是真正的值
Object[] argsToUse = null;

//确定参数值列表
//argsToUse可以有两种办法设置
//第一种通过beanDefinition设置
//第二种通过xml设置
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;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}

if (constructorToUse == null) {
//如果没有已经解析的构造方法
//则需要去解析构造方法
//判断构造方法是否为空,判断是否根据构造方法自动注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;

//定义了最小参数个数 minNrOfArgs
//如果你给构造方法的参数列表给定了具体的值
//那么这些值得个数就是构造方法参数的个数
int minNrOfArgs;
if (explicitArgs != null) {
//如果传递过来的参数不为null,那就以传递过来的参数个数作为“最小参数个数”
minNrOfArgs = explicitArgs.length;
}
else {
//mybatis:mbd.getConstructorArgumentValues().addGenericArgumentValue("com.index.dao");
//实例一个对象,用来存放构造方法的参数值
//当中主要存放了参数值和参数值所对应的下表
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
/**
* 确定构造方法参数数量,假设有如下配置:
* <bean id="llsydn" class="com.llsydn.Luban">
* <constructor-arg index="0" value="str1"/>
* <constructor-arg index="1" value="1"/>
* <constructor-arg index="2" value="str2"/>
* </bean>
*
* 在通过spring内部给了一个值的情况,那么表示你的构造方法的“最小参数个数”是确定的
*
* minNrOfArgs = 3
*/
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

// Take specified constructors, if any.
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);
}
}
//怎么排序的呢?
//1.根据构造方法的访问权限级别 public -- protected -- private
//2.根据构造方法的参数数量进行排序 从多到小
/**
* 有限反问权限,继而参数个数
* 这个自己可以写个测试去看看到底是不是和我说的一样
* 1. public Luban(Object o1, Object o2, Object o3)
* 2. public Luban(Object o1, Object o2)
* 3. public Luban(Object o1)
* 4. protected Luban(Integer i, Object o1, Object o2, Object o3)
* 5. protected Luban(Integer i, Object o1, Object o2)
* 6. protected Luban(Integer i, Object o1)
*/
AutowireUtils.sortConstructors(candidates);
//定义了一个差异变量,这个变量很有分量,后面有注释
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null; //记录异常的构造方法(构造方法差异值一样,spring不知怎么选择)
LinkedList<UnsatisfiedDependencyException> causes = null;

//循环所有的构造方法
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
/**
* 这个判断别看只有一行代码理解起来很费劲
* 首先constructorToUse != null这个很好理解
* 前面已经说过首先constructorToUse主要是用来装已经解析过了并且在使用的构造方法
* 只有在他等于空的情况下,才有继续的意义,因为下面如果解析到了一个符合的构造方法
* 就会赋值给这个变量(下面注释有写)。故而如果这个变量不等于null就不需要再进行解析了,说明spring已经
* 找到一个合适的构造方法,直接使用便可以
* argsToUse.length > paramTypes.length这个代码就相当复杂了
* 首先假设 argsToUse = [1,"llsydn",obj]
* 那么回去匹配到上面的构造方法的1和5
* 由于构造方法1有更高的访问权限,所有选择1,尽管5看起来更加匹配
* 但是我们看2,直接参数个数就不对所以直接忽略
*
*/
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
//如果遍历的当前构造方法的参数类型的长度,不等于最小的参数格式:证明不能用该构造方法实例化对象
if (paramTypes.length < minNrOfArgs) {
continue;
}

ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
//判断是否加了ConstructorProperties注解如果加了则把值取出来
//可以写个代码测试一下
//@ConstructorProperties(value = {"xxx", "111"})
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取构造方法参数名称列表
/**
* 假设你有一个(String llsydn, Object zilu)
* 则paramNames=[llsydn,zilu]
*/
paramNames = pnd.getParameterNames(candidate);
}
}

//获取构造方法参数值列表
/**
* 这个方法比较复杂
* 因为spring只能提供字符串的参数值
* 故而需要进行转换
* argsHolder所包含的值就是转换之后的
*
* 例如:在xml配置文件设置了“order”这是一个字符串,要转成order对象
*/
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
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 {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}

/**
* typeDiffWeight 差异量,何谓差异量呢?
* argsHolder.arguments和paramTypes之间的差异
* 每个参数值得类型与构造方法参数列表的类型直接的差异
* 通过这个差异量来衡量或者确定一个合适的构造方法
*
* 值得注意的是constructorToUse=candidate
*
* 第一次循环一定会typeDiffWeight < minTypeDiffWeight,因为minTypeDiffWeight的值非常大
* 然后每次循环会把typeDiffWeight赋值给minTypeDiffWeight(minTypeDiffWeight = typeDiffWeight)
* else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight)
* 第一次循环肯定不会进入这个
* 第二次如果进入了这个分支代表什么?
* 代表有两个构造方法都符合我们要求?那么spring有迷茫了(spring经常在迷茫)
* spring迷茫了怎么办?
* ambiguousConstructors.add(candidate);
* 顾名思义。。。。
* ambiguousConstructors=null 非常重要?
* 为什么重要,因为需要清空
* 这也解释了为什么他找到两个符合要求的方法不直接抛异常的原因
* 如果这个ambiguousConstructors一直存在,spring会在循环外面去exception
* 很牛逼呀!!!!
*/
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
//第一遍100%会进这里;当找到差异值更小的,就将异常清空。
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
//清空异常的构造器
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
//这里表示,找到了差异值一样的构造参数,spring不知道怎么选择,就先记录在ambiguousConstructors。
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)");
}

//如果ambiguousConstructors还存在则异常?为什么会在上面方法中直接exception?
//上面注释当中有说明
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) {
/*
* 缓存相关信息,比如:
* 1. 已解析出的构造方法对象 resolvedConstructorOrFactoryMethod
* 2. 构造方法参数列表是否已解析标志 constructorArgumentsResolved
* 3. 参数值列表 resolvedConstructorArguments 或 preparedConstructorArguments
* 这些信息可用在其他地方,用于进行快捷判断
*/
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
/*
* 使用反射创建实例 lookup-method 通过CGLIB增强bean实例
*/
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;

if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
//最后:通过找到constructorToUse构造方法,进行实例化对象
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}

autowireConstructor使用特殊构造方法实例化对象,主要做了几步操作:
1.判断要用哪个构造方法实例化对象:constructorToUse,那些参数:argsToUse
2.先决定构造方法的最小参数个数:minNrOfArgs。
3.对所有的构造方法进行排序,排序规则:访问权限级别(public–protected–private) 和 参数数量(从多到小)
4.遍历所有构造方法,根据“最小参数个数”minNrOfArgs去判断构造方法是否符合
5.计算构造方法的“typeDiffWeight 差异量”,找到最小的差异量,spring就用这个构造方法实例化对象。
6.如果spring找到了多个差异量一样的,也符合最小参数个数的构造方法,就记录在ambiguousConstructors。
7.如果这个ambiguousConstructors一直存在,spring会在循环外面去exception
8.如果这个ambiguousConstructors为null,spring就会缓存找到的constructorToUse的构造方法
9.最后通过找到constructorToUse构造方法,进行实例化对象。

1.instanceWrapper = createBeanInstance(beanName, mbd, args);

至此,使用构造方法实例化对象的方法就解析到这里。创建的对象,就执行下面这步

2.addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

这个很重要,主要将刚new的对象,存放在singletonFactories对象。主要是用来解决循环依赖。

3.populateBean(beanName, mbd, instanceWrapper);
但是这个时候,对象还没进行属性赋值,需要调用该方法进行属性赋值

  • populateBean(beanName, mbd, instanceWrapper);
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
java复制代码protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
//是否需要属性赋值
boolean continueWithPropertyPopulation = true;

//实现InstantiationAwareBeanPostProcessor接口,就可以不进行属性赋值,返回一个寡对象
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}

//属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

//判断属性自动装配模型(NO)
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

//是否需要处理InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要深度检查(循环引用)
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//拿到所有get和set的方法
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}

if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

这里进行属性赋值,主要是调用了两个BeanPostProcessor进行属性赋值。
1.AutowiredAnnotationBeanPostProcessor(处理@Autowired注解)
2.CommonAnnotationBeanPostProcessor(处理@Resource、@PostConstruct和@PreDestroy注解)

  • AutowiredAnnotationBeanPostProcessor源码解析
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
java复制代码// @Autowired实现属性注入
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

//找出类中被@Autowired注解的属性和方法
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//属性的注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//拿到需要注入的属性
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
//遍历一个一个注入属性
for (InjectedElement element : elementsToIterate) {
if (logger.isDebugEnabled()) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
//属性注入
element.inject(target, beanName, pvs);
}
}
}

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//拿到要注入的属性
Field field = (Field) this.member;
Object value;
if (this.cached) {
//如果被缓存了,从缓存里面拿
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//从BeanFactory中转换这个依赖(重要)
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();

//这里isTypeMatch,就是从earlySingletonObjects中拿出“自动装配的bean”的类型是否相同
//如果类型相同,就真正的set值field.set(bean, value);
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}

@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()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//真正干活的方法,从BeanFactory中转换这个依赖
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}

Class<?> type = descriptor.getDependencyType();
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());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}

Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}

String autowiredBeanName;
Object instanceCandidate;

if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}

if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
//处理自动装配属性,进行转换。@Autowired 重要
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 {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
//再次调用了getBean方法
return beanFactory.getBean(beanName);
}

进行属性赋值,就可能会出现循环依赖的情况:
例如:A类有一个B类的属性,B类有一个A类的属性。
那么在属性填充的时候,就会出现在创建A对象的时候,然后自动装配B,那么spring也会去创建B对象。那么这个时候,就会有一个循环依赖的情况。
那么spring是怎么解决循环依赖的?

  • 在处理循环依赖的情况,spring主要用了3个map,1个list,最重要的就是singletonFactories
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
java复制代码//这个时候bean已经被创建出来,但是还没进行属性装配
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
//singletonObjects是完整的对象
if (!this.singletonObjects.containsKey(beanName)) {
//已经被new出来,但是属性没有被填充,主要是解决循环依赖
this.singletonFactories.put(beanName, singletonFactory);
//已经被new出来,但是属性没有被填充,主要是作为类型校验
this.earlySingletonObjects.remove(beanName);
//在registeredSingletons记录一下
this.registeredSingletons.add(beanName);
}
}
}

//进行属性赋值的时候,调用该方法,从singletonFactories中拿到那些依赖的bean,进行属性赋值
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从map中获取bean如果不为空直接返回,不再进行初始化工作
//讲道理一个程序员提供的对象这里一般都是为空的
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}

至此,spring对bean的实例化过程,就解析到这里了。
下面上spring实例化过程的流程图:

  • 在这里插入图片描述

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%