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

SpringIOC-依赖注入实现

AutowiredAnnotationBeanPostProcessor类

AutowiredAnnotationBeanPostProcessor继承了InstantiationAwareBeanPostProcessor,这两个注解是由这个父类完成解析的,在AutowiredAnnotationBeanPostProcessor构造函数中在autowiredAnnotationTypes集合中添加了@Autowired,@Value的注解,主要是对@Autowired,@Value注解的支持。

determineCandidateConstructors

从缓存中获取构造函数数组

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
//从缓存中获取构造函数数组
// 1.构造函数解析,首先检查是否存在于缓存中
// Quick check on the concurrent map first, with minimal locking.
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
// 2.加锁进行操作
synchronized (this.candidateConstructorsCache) {
//再次从缓存中获取造函数数组 为了线程安全考虑
// 3.再次检查缓存,双重检测
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// 存放原始的构造函数(候选者)
Constructor<?>[] rawCandidates;
try {
//获取bean对应的所有构造器
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
// 存放使用了@Autowire注解的构造函数
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
// 存放使用了@Autowire注解,并且require=true的构造函数
Constructor<?> requiredConstructor = null;
// 存放默认的构造函数
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 5.遍历原始的构造函数候选者
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
} else if (primaryConstructor != null) {
continue;
}
// 6.获取候选者的注解属性
//获取到构造函数上的@Autowired注解信息,这个方法可以不看
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
//如果没有找到Autowired注解
if (ann == null) {
// 7.如果没有从候选者找到注解,则尝试解析beanClass的原始类(针对CGLIB代理)
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
//根据参数获取构造函数
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
//检查构造方法是否有Autowired注解
ann = findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
//如果找到Autowired注解的构造函数
// 8.如果该候选者使用了@Autowire注解
if (ann != null) {
if (requiredConstructor != null) {
// 8.1 之前已经存在使用@Autowired(required = true)的构造函数,则不能存在其他使用@Autowire注解的构造函数,否则抛异常
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取到@Autowired里面的required方法的值
// 8.2 获取注解的require属性值
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
// 8.3 如果当前候选者是@Autowired(required = true),则之前不能存在其他使用@Autowire注解的构造函数,否则抛异常
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// 8.4 如果该候选者使用的注解的required属性为true,赋值给requiredConstructor
requiredConstructor = candidate;
}
// 8.5 将使用了@Autowire注解的候选者添加到candidates
candidates.add(candidate);
} else if (candidate.getParameterCount() == 0) {
// 8.6 如果没有使用注解,并且没有参数,则为默认的构造函数
defaultConstructor = candidate;
}
}
// 9.如果存在使用了@Autowire注解的构造函数
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 9.1 但是没有使用了@Autowire注解并且required属性为true的构造函数
if (requiredConstructor == null) {
if (defaultConstructor != null) {
// 9.2 如果存在默认的构造函数,则将默认的构造函数添加到candidates
candidates.add(defaultConstructor);
} else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
// 9.3 将所有的candidates当作候选者
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
} else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
// 10.如果candidates为空 && beanClass只有一个声明的构造函数(非默认构造函数),则将该声明的构造函数作为候选者
candidateConstructors = new Constructor<?>[]{rawCandidates[0]};
} else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[]{primaryConstructor, defaultConstructor};
} else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[]{primaryConstructor};
} else {
// 11.否则返回一个空的Constructor对象
candidateConstructors = new Constructor<?>[0];
}
//将构造函数加入缓存
// 12.将beanClass的构造函数解析结果放到缓存
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
//返回构造函数
// 13.返回解析的构造函数
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

​ 关于 8.1 和 8.3 的异常校验,说的简单点:在一个 bean 中,只要有构造函数使用了 “@Autowired(required = true)” 或 “@Autowired”,就不允许有其他的构造函数使用 “@Autowire”;但是允许有多个构造函数同时使用 “@Autowired(required = false)”。

findAutowiredAnnotation

查找Autowired的注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 查找Autowired的注解
* @param ao 属性 方法 构造函数的父类
* @return
*/
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
// 1.判断ao是否有被注解修饰
MergedAnnotations annotations = MergedAnnotations.from(ao);
// 2.检查是否有autowiredAnnotationTypes中的注解:@Autowired、@Value(@Value无法修饰构造函数)
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
// 3.拿到注解的合并注解属性,@Autowire在这边拿到,required=true(默认属性)
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}

postProcessMergedBeanDefinition

postProcessMergedBeanDefinition 被定义在 MergedBeanDefinitionPostProcessor 接口中,该方法的主要作用是:对指定 bean 的给定 MergedBeanDefinition 进行后置处理。

在 AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行预解析,并放到 injectionMetadataCache 缓存中,用于后续使用。

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 1、扫描类里面的属性或者方法
* 2、判断属性或者方法上面是否有@Autowiring注解
* 3、如果有注解的属性或者方法,包装成一个类
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//1. 搜集方法以及字段的@Autowired注解并封装成InjectionMetadata
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
//2. 检测ConfigMembers并将InjectedElement集合赋值给全局的checkedElements
metadata.checkConfigMembers(beanDefinition);
}

findAutowiringMetadata

搜集方法以及字段的@Autowired注解并封装成InjectionMetadata

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
/**
* 搜集方法以及字段的@Autowired注解并封装成InjectionMetadata
*/
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
// 1.设置cacheKey的值(beanName 或者 className)
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// 2.检查beanName对应的InjectionMetadata是否已经存在于缓存中
//从缓存给中获取metadata
//因为已经上一步已经搜集过了可以直接从缓存中拿到
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
// 3.检查InjectionMetadata是否需要刷新(为空或者class变了)
//检查是否刷新如果metadata为null或者class 不匹配就刷新
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
// 4.加锁后,再次从缓存中获取beanName对应的InjectionMetadata
//从缓存给中获取metadata
metadata = this.injectionMetadataCache.get(cacheKey);
// 5.加锁后,再次检查InjectionMetadata是否需要刷新
//双重检查锁
//检查是否刷新如果metadata为null或者class 不匹配就刷新
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
// 6.如果需要刷新,并且metadata不为空,则先移除
metadata.clear(pvs);
}
// 7.解析@Autowired注解的信息,生成元数据(包含clazz和clazz里解析到的注入的元素,
// 这里的元素包括AutowiredFieldElement和AutowiredMethodElement)
metadata = buildAutowiringMetadata(clazz);
// 8.将解析的元数据放到injectionMetadataCache缓存,以备复用,每一个类只解析一次
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}

​ injectionMetadataCache是一个Map对象,缓存beanName与InjectionMetadata。InjectionMetadata对象通过buildAutowiringMetadata()方法来创建的。

buildAutowiringMetadata

搜集方法以及字段的@Autowired注解并封装成InjectionMetadata

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
/**
* 搜集方法以及字段的@Autowired注解并封装成InjectionMetadata
*
* @param clazz
* @return
*/
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
//1. 检查clazz中是否包含@Autowired以及@Value注解
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
//1.1 如果不包含直接返回
return InjectionMetadata.EMPTY;
}

// 2.用于存放所有解析到的注入的元素的变量
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
// 3.循环遍历
do {
// 3.1 定义存放当前循环的Class注入的元素(有序)
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 3.2 如果targetClass的属性上有@Autowired注解,则用工具类获取注解信息
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 3.2.1 获取field上的@Autowired注解信息
//找到有@Autowired注解的字段
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 3.2.2 校验field是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的field
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 3.2.3 获取@Autowired注解的required的属性值(required:值为true时,如果没有找到bean时,自动装配应该失败;false则不会)
boolean required = determineRequiredStatus(ann);
//生成AutowiredFieldElement对象并加入到currElements
// 3.2.4 将field、required封装成AutowiredFieldElement,添加到currElements
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 3.3 如果targetClass的方法上有@Autowired注解,则用工具类获取注解信息
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//3.3.1. 找出我们在代码中定义的方法而非编译器为我们生成的方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 3.3.2 判断方法的可见性,如果不可见则直接返回
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
//根据@Autowired注解查找对应的方法
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
//3.3.3. 如果重写了父类的方法,则使用子类的
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 3.3.4 校验method是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的method
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// 3.3.5 @Autowired注解标识在方法上的目的就是将容器内的Bean注入到方法的参数中,没有参数就违背了初衷
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 3.3.6 获取@Autowired注解的required的属性值
boolean required = determineRequiredStatus(ann);
// 3.3.7 获取method的属性描述器
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
//生成AutowiredFieldElement对象并加入到currElements
// 3.3.8 将method、required、pd封装成AutowiredMethodElement,添加到currElements
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 3.4 将本次循环获取到的注解信息添加到elements
//将currElements添加到elements
elements.addAll(0, currElements);
//将targetClass的父类赋值给targetClass
// 3.5 在解析完targetClass之后,递归解析父类,将所有的@Autowired的属性和方法收集起来,且类的层级越高其属性会被越优先注入
targetClass = targetClass.getSuperclass();
}
//3.6 如果targetClass不是Object继续循环
while (targetClass != null && targetClass != Object.class);
//将elements封装成InjectionMetadata
// 3.7 将clazz和解析到的注入的元素封装成InjectionMetadata
return InjectionMetadata.forElements(elements, clazz);
}

​ buildAutowiringMetadata()方法分为对字段与方法的@Autowired(@Value,@Inject)注解处理。将标记@Autowired的费静态字段封装为AutowiredFieldElement对象,将标记@Autowired的非静态方法封装到AutowiredMethodElement对象然后都加入到InjectionMetadata中,此过程是一个循环过程此类处理完会沿着父类继续向上处理。AutowiredFieldElement与AutowiredMethodElement都是InjectionMetadata.InjectedElement的子类,都覆盖了父类的inject()方法这个下面会介绍。

​ 通过findAutowiringMetadata()方法得到了InjectionMetadata对象之后调用了给对象的checkConfigMembers()方法。这个方法就是将上面保存的InjectedElement对象筛选出那些不存在于beanDefinition中的赋值给checkedElements。

checkConfigMembers

检测ConfigMembers并将InjectedElement集合赋值给全局的checkedElements

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
/**
* 检测ConfigMembers并将InjectedElement集合赋值给全局的checkedElements
*
* @param beanDefinition
*/
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
//1. initMethod方法的检查以及设置
//遍历检查所有的收集的injectedElement元素
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
// 2.如果beanDefinition的externallyManagedConfigMembers属性不包含该member
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
// 3.将该member添加到beanDefinition的externallyManagedConfigMembers属性
beanDefinition.registerExternallyManagedConfigMember(member);
// 4.并将element添加到checkedElements
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
//5. 对checkedElements进行赋值
this.checkedElements = checkedElements;
}

​ 到这为止就是postProcessMergedBeanDefinition()方法的全部实现逻辑并没有做什么实际事情,其实是为了后面的行为做铺垫,请看postProcessPropertyValues()方法,此方法是在属性填充阶段被调用的。

postProcessPropertyValues

postProcessPropertyValues 被定义在 InstantiationAwareBeanPostProcessor 接口中,该方法的主要作用是:将属性值应用于给定 bean 之前对给定属性值进行后置处理。

在 AutowiredAnnotationBeanPostProcessor 的实现中,主要是对使用了 @Autowire 注解的方法和属性进行自动注入,将依赖的 bean 赋值给对应的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* autowirted 依赖注入实现
*
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//1. 获取搜集到的class中需要注入的metadata,因为上一步已经搜集过了可以从缓存中直接拿到
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 2.InjectionMetadata: 执行inject()方法,开始执行属性注入或方法注入
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;
}

​ 首先调用 findAutowiringMetadata()方法从缓存中再次取到InjectionMetadata对象,调用inject()方法完成autowired注入。

InjectionMetadata.inject

进行依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 进行依赖注入
*
*/
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//1. 从checkedElements中获取需要注入的元素
Collection<InjectedElement> checkedElements = this.checkedElements;
//2. 如果checkedElements存在,则使用checkedElements,否则使用injectedElements
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
//3. 遍历需要注入的元素
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
//4.进行依赖注入
element.inject(target, beanName, pvs);
}
}
}

​ 因为之前已经把类@Autowired注解标记的字段或方法封装到了响应的InjectedElement子类中了,此时依次调用子类的inject()方法完成对象的注入,下面分别看一看这两种注入的实现。

依赖注入

解析 @Autowired 注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement,这两个类继承InjectionMetadata.InjectedElement,各自重写了 inject 方法。对于属性注入来说,会走到 AutowiredFieldElement 中的 inject 方法

AutowiredFieldElement#inject

属性的依赖注入

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
/**
* 属性的依赖注入
*/
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 1.拿到该元数据的属性值
Field field = (Field) this.member;
Object value;
// 2.如果缓存中已经存在,则直接从缓存中解析属性
if (this.cached) {
//获取缓存中的参数
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
// 3.将field封装成DependencyDescriptor
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
//设置class
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 4.解析当前属性所匹配的bean实例,并把解析到的bean实例的beanName存储在autowiredBeanNames中
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
// 5.value不为空或者required为true
if (value != null || this.required) {
// 6.如果属性依赖注入的bean不止一个(Array,Collection,Map),缓存cachedFieldValue放的是DependencyDescriptor
this.cachedFieldValue = desc;
// 7.注册依赖关系到缓存(beanName 依赖 autowiredBeanNames)
registerDependentBeans(beanName, autowiredBeanNames);
// 8.如果属性依赖注入的bean只有一个(正常都是一个)
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
// @Autowired标识属性类型和Bean的类型要匹配,因此Array,Collection,Map类型的属性不支持缓存属性Bean名称
// 9.检查autowiredBeanName对应的bean的类型是否为field的类型
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 10.将该属性解析到的bean的信息封装成ShortcutDependencyDescriptor,
// 以便之后可以通过getBean方法来快速拿到bean实例
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
} else {
this.cachedFieldValue = null;
}
// 11.缓存标识设为true
this.cached = true;
}
}
}
if (value != null) {
// 12.设置字段访问性
ReflectionUtils.makeAccessible(field);
// 13.通过反射为属性赋值,将解析出来的bean实例赋值给field
field.set(bean, value);
}
}

解析当前属性所匹配的 bean 实例,并把解析到的 bean 实例的 beanName 存储在 autowiredBeanNames 中

registerDependentBeans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Register the specified bean as dependent on the autowired beans.
* 注册依赖的bean
*/
private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) {
if (beanName != null) {
// 1.遍历所有autowiredBeanNames
for (String autowiredBeanName : autowiredBeanNames) {
//如果beanFactory有这个依赖的bean
if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
// 2.如果autowiredBeanName在BeanFactory中存在,则注册依赖关系到缓存(beanName 依赖 autowiredBeanName)
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName +
"' to bean named '" + autowiredBeanName + "'");
}
}
}
}

​ 如果 autowiredBeanName 在 BeanFactory 中存在,则注册依赖关系到缓存(beanName 依赖 autowiredBeanName

AutowiredMethodElement#inject

方法的依赖注入

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
/**
* 方法的依赖注入
*/
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
// 1.拿到该元数据的属性值
Method method = (Method) this.member;
Object[] arguments;
// 2.如果缓存中已经存在,则直接从缓存中解析属性
if (this.cached) {
// Shortcut for avoiding synchronization...
//2.1 获取对象方法(依赖对象)的参数
arguments = resolveCachedArguments(beanName);
} else {
//3. 获取方法参数(依赖对象)
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
//4. 根据参数(依赖对象)创建DependencyDescriptor数组
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
//5. 获取参数(依赖对象)类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
//6. 遍历所有参数
for (int i = 0; i < arguments.length; i++) {
//6.1 创建方法参数(依赖对象)的封装
MethodParameter methodParam = new MethodParameter(method, i);
//6.2 将方法参数(依赖对象)封装成DependencyDescriptor
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
//设置BenaClass
currDesc.setContainingClass(bean.getClass());
//进行数组赋值
descriptors[i] = currDesc;
try {
// 6.3 解析当前属性所匹配的bean(依赖对象)实例,并把解析到的bean实例的beanName存储在autowiredBeanNames中
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
//6.4 如果获取到的参数(依赖对象)为空 && 并且是非required的
if (arg == null && !this.required) {
// 将 参数设置为空
arguments = null;
//并跳出循环
break;
}
//6.5 否则设置数组参数(依赖对象)
arguments[i] = arg;
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
//7. 对依赖对象进行数组拷贝
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
//8. 注册依赖关系到缓存(beanName 依赖 autowiredBeanNames)
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
//9. 创建autowiredBeans的迭代器
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
// @Autowired标识属性类型和Bean的类型要匹配,因此Array,Collection,Map类型的属性不支持缓存属性Bean名称
// 10.检查autowiredBeanName对应的bean的类型是否为field的类型
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
// 11.将该属性解析到的bean的信息封装成ShortcutDependencyDescriptor,
// 以便之后可以通过getBean方法来快速拿到bean实例
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
} else {
this.cachedMethodArguments = null;
}
// 12.缓存标识设为true
this.cached = true;
}
}
}
if (arguments != null) {
try {
// 13.设置字段访问性
ReflectionUtils.makeAccessible(method);
//14. 反射调用方法注入
method.invoke(bean, arguments);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}

评论