属性注入(populateBean)
处理 @Autowired 和 @Resource 标记的属性和方法(这里的方法不包括构造方法,因为构造方法在前面已经完成了推断)
问题:@Autowired 是 byType?,再 byName?
流程:
- 根据需要注入的类型找到所有的 beanName
- 遍历 beanName,找到需要注入的类型,并放入一个集合中(待推断)
- 如果待注入集合中只有一个符合条件的 class,则表示找到了要注入的 bean
- 如果带注入集合中有多个符合条件的 class,则继续按名称推断
- 看看有没有标记为 @Primary 注解的 bean,有则返回
- 判断有没有 @Priority 注解的 bean,有的话,返回值低的优先级作为 bean 返回
- 看看是不是有别名 bean 符合,有的话作为 bean 返回
- 如果都不满足,则抛出异常 NoUniqueBeanDefinitionException
- 根据 beanName 从单例池中获取所需要注入的 bean
- 利用反射完成属性注入
调用后置处理器
这里的后置处理器必须是 InstantiationAwareBeanPostProcessor 类型
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// ★★★ 关键代码:进行属性填充
// CommonAnnotationBeanPostProcessor 完成对 @Resource 属性的注入
// AutowiredAnnotationBeanPostProcessor 完成对 @Autowired 属性的注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
查找类的注入元数据(包括属性,方法)
根据当前要进行属性填充的 bean,找到当前 bean 需要注入的元数据(属性和方法)
// ★★★ 获取需要注入的元数据
// 1、查找标记有 @Autowired 的 field
// 2、查找标记有 @Autowired 的 method
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
根据类型查找
matchingBeans 很关键,先根据类型查找,看存在多少相同类型的 bean
- beanName:当前需要进行属性注入的 bean
- type:当前注入的属性的类型
- descriptor:当前注入的属性的包装,包括字段名称,类型,是不是方法等信息
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
根据名称查找
// ★★★ 如果找到多个符合条件的 bean
// matchingBeans.size() > 1:则说明通过类型查找找到了多个符合条件的 bean
if (matchingBeans.size() > 1) {
// ★★★ 关键代码:开始根据名称进行推断,根据 descriptor 提供的 fieldName 来推断 autowiredBeanName
// 由此可以推断,@Autowired 是先根据类型查找,如果找到多个,再根据名称查找
// 此处根据需要注入的属性的名字推断,查找真正需要注入的 bean
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;
}
}
// ★ 从多个匹配的对象中根据 autowiredBeanName 获取 bean
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();
}
标记为 Lazy 的属性
如果有标记为 @Lazy 的注入属性,Spring 并不会立即进行属性注入
// 获取 @Lazy 的注入属性
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// ★★★ 关键代码:解析依赖
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;