0. 举个栗子:
@Component
public class SetterBean {
@Autowired
@Qualifier("beanService")
private BeanService beanService;
}
@Configuration
public class ConfigurationBean {
@Bean(autowireCandidate = false)
public BeanService beanService1() {
return new BeanServiceImpl();
}
@Bean
public BeanService beanService() {
BeanServiceImpl beanService = new BeanServiceImpl();
beanService.setName("zhangsan");
return beanService;
}
}
3. doResolveDependency:
上一篇文章介绍了populateBean属性填充方法,其中通过resolveDependency方法来解析出依赖的属性bean对象,再进行反射
·
而resolveDependency通常又调用doResolveDependency
来解析出依赖的属性bean对象
·
针对上述栗子,下文省略一些不必要的内容(注入集合、@Value的场景),后面再介绍.
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//设置当前的descriptor(存储了方法参数等信息)为当前注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
//从descriptor中获取属性类型
Class<?> type = descriptor.getDependencyType();
... ... .... // 省略一些不必要的内容(注入集合、@Value的场景)代码
// 查找符合注入属性类型的bean,下文3.1有介绍
// 这里过滤了 @Bean(autowireCandidate = false)和不符合@Qualifier("beanName")的bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 为空说明找不到该注入类型的bean,如果注入的属性又是必须的,则抛NoSuchBeanDefinitionException
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 查找到多个符合注入属性类型的bean
if (matchingBeans.size() > 1) {
// 再过滤找到最优的beanName,进而获取最优的用来创建实例的候选者instanceCandidate
// 这里挑选@primary、@Priority等优先级高的bean,细节见下文3.3
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// 找不到最优的beanName,注入的属性又是必须的,则抛NoUniqueBeanDefinitionException异常
// 注入的属性非必须,未过滤前就有多个注入属性类型的bean,如果注入的属性不是集合,也抛异常
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
// 根据beanName获取最优的用来创建属性实例的候选者instanceCandidate
// key:beanName;value:符合注入属性类型的bean或者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();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// resolveCandidate调用getBean(),根据候选beanName进行属性bean的系列生命周期后返回完整的属性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 {
// 和前面那个一样,暂时不知道什么场景有用
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
3.1. findAutowireCandidates:
这里查找符合注入属性类型的bean,会过滤@Bean(autowireCandidate = false)和不符合@Qualifier(“beanName”)的bean
·
像本栗子的beanService1就会被过滤掉,具体过滤细节见下文3.2
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 从已经解析的依赖关系缓存中寻找是否存在我们想要的类型,通常都美誉
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// isSelfReference 判断是否是自引用,即注入属性为自身类型
// isAutowireCandidate 判断是否有资格作为依赖注入的候选者,@Bean(autowireCandidate = false)注解的bean就没有资格
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 不是自引用又有资格,封装result,见下文3.4.1
//(key:beanName;value:符合注入属性类型的bean或者bean类型)
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 没有符合注入属性类型的beanName
if (result.isEmpty()) {
// 注入的属性是否是bean的集合类型,本栗子不是
boolean multiple = indicatesMultipleBeans(requiredType);
// 使用备用的依赖描述器再去获取一遍符合注入属性类型的beanName
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 还是没有符合注入属性类型的beanName,又不是集合类型,考虑自引用,符合条件则将候选者添加到result中
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.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
3.2. isAutowireCandidate:
该方法最后会调用AutowireCandidateResolver解析器的resolver.isAutowireCandidate方法来解析候选者bean是否有注入资格
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
resolveBeanClass(mbd, bdName);
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
BeanDefinitionHolder holder = (beanName.equals(bdName) ?
this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
return resolver.isAutowireCandidate(holder, descriptor);
}
在了解isAutowireCandidate前,先了解AutowireCandidateResolver接口实现类的AutowireCandidateResolver方法,类图如下:
3.2.1. SimpleAutowireCandidateResolver#isAutowireCandidate:
SimpleAutowireCandidateResolver 是一个简单的解析器,直接取bd.autowireCandidate值,默认为true,也就是可注入
·
本栗子beanService1使用 @Bean(autowireCandidate = false),即这个bean的autowireCandidate为false,不可注入
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
3.2.2. GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate:
GenericTypeAwareAutowireCandidateResolver 是一个泛型依赖的解析器
- 先调用父类SimpleAutowireCandidateResolver来判断该候选bean是否可注入,允许则进行泛型匹配
- 主要在checkGenericTypeMatch方法匹配泛型:
- 如果待依赖注入的属性类型不包含泛型,直接返回true,即这个候选bean允许取注入,本栗子不涉及泛型,返回true
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
return false;
}
return checkGenericTypeMatch(bdHolder, descriptor);
}
3.2.3. QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate:
QualifierAnnotationAutowireCandidateResolver是处理@Qualifier注解的解析器
- 先调用父类(即上述候选解析器)判断是否允许注入、泛型匹配
- 都满足则进行待依赖注入属性的@Qualifier匹配,匹配成功返回true,即这个候选bean允许注入
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 父类校验:判断是否允许注入、泛型匹配
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
// checkQualifiers来校验@Qualifier规则,第二个参数传属性注解信息数组
// bdHolder相当于候选bean,即符合属性类型的bean;descriptor是待依赖注入属性bean的描述器
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
// 进一步校验标注在构造函数或方法上的@Qualifier注解规则
if (match) {
MethodParameter methodParam = descriptor.getMethodParameter();
// 如果当前是依赖注入属性,methodParam=null,注解返回match
if (methodParam != null) {
Method method = methodParam.getMethod();
// 校验标注在构造函数或方法上的@Qualifier注解规则
if (method == null || void.class == method.getReturnType()) {
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
3.2.4. checkQualifiers:
循环遍历属性上的注解,看是否是@Qualifier,是的话通常会取匹配注解的属性值是否和属性beanName一致
·
一致则不需要进行元注解匹配,否则会遍历一层元注解,进行元注解匹配,因为Spring还支持@Qualifier派生注解
·
关于元注解可以参考:链接的3.3的内容
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
if (ObjectUtils.isEmpty(annotationsToSearch)) {
return true;
}
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
// 遍历属性注解信息数组
for (Annotation annotation : annotationsToSearch) {
Class<? extends Annotation> type = annotation.annotationType();
boolean checkMeta = true;
boolean fallbackToMeta = false;
// 判断是不是@Qualifier注解
if (isQualifier(type)) {
// 通常会取匹配注解的属性值是否和候选bean的beanName一致
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
// 表示第一次匹配失败,进而往下进行元注解匹配
fallbackToMeta = true;
}
else {
// 匹配成功,就不用往下进行元注解匹配
checkMeta = false;
}
}
// 本身不是@Qualifier或匹配失败都会进行元注解匹配
if (checkMeta) {
boolean foundMeta = false;
// 遍历元注解,也就是注解里的注解。只遍历一层元注解
for (Annotation metaAnn : type.getAnnotations()) {
Class<? extends Annotation> metaType = metaAnn.annotationType();
// 判断元注解是不是@Qualifier注解
if (isQualifier(metaType)) {
foundMeta = true;
// 元注解匹配
if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
}
}
}
// 两次都匹配失败,则false
if (fallbackToMeta && !foundMeta) {
return false;
}
}
}
return true;
}
3.2.5. isAutowireCandidate小结:
该方法最后会调用resolver.isAutowireCandidate,经过不同的解析器去处理,返回true即这个候选bean可以注入:
- 简单候选解析器去判断autowireCandidate是否是true
- 泛型候选解析器去匹配泛型,本栗子不是泛型返回true
- @Qualifier注解的解析器去匹配@Qualifier规则(通常匹配属性是否是@Qualifier注解和注解属性值),匹配成功返回true
3.3. determineAutowireCandidate:
经过findAutowireCandidates匹配(也就是autowireCandidate和@Qualifier匹配)后,还存在多个候选bean
·
则在此处筛选出最优的候选bean,涉及@Primary、@Priority注解
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
// 获取待依赖注入属性的类型
Class<?> requiredType = descriptor.getDependencyType();
// 先匹配候选bean是有@Primary
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
// 通过@Primary成功,返回候选bean的beanName
if (primaryCandidate != null) {
return primaryCandidate;
}
// @Primary匹配失败,再通过@Priority进行优先级匹配,属性值越小优先级越高
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
// @Priority高优先级匹配成功,返回候选bean的beanName
if (priorityCandidate != null) {
return priorityCandidate;
}
// @Primary、@Priority都匹配失败,最后匹配候选beanName和属性beanName是否一致,一致则返回候选bean的beanName
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
// 匹配失败,表示没有符合的bean可以注入
return null;
}
3.3.0. 栗子:
@Configuration
public class ConfigurationBean {
@Bean
// @Primary
public BeanService beanService1() {
return new BeanServiceImpl();
}
@Bean
public BeanService beanService() {
BeanServiceImpl beanService = new BeanServiceImpl();
beanService.setName("zhangsan");
return beanService;
}
}
@Component
public class SetterBean {
@Autowired
private BeanService beanService;
}
@Component
@Priority(1)
public class BeanServicePriority implements BeanService {
private String name;
public void setName(String name) {
this.name = name;
}
}
3.3.1. determinePrimaryCandidate:
循环遍历候选bean上是否有@Primary注解(判断bd.primary,默认false,有注解时为true)
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String primaryBeanName = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 循环遍历候选bean上是否有@Primary注解,只能一个候选bean有注解
if (isPrimary(candidateBeanName, beanInstance)) {
// 不等于null,说明已经有过候选bean是@Primary注解的
if (primaryBeanName != null) {
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
// 多个候选bean标注@Primary注解,通常抛异常
if (candidateLocal && primaryLocal) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
}
else if (candidateLocal) {
primaryBeanName = candidateBeanName;
}
}
else {
// @Primary匹配成功,作为待返回的候选beanName
primaryBeanName = candidateBeanName;
}
}
}
return primaryBeanName;
}
3.3.2. determineHighestPriorityCandidate:
循环遍历获取候选bean的@Priority(1)注解的优先级,优先级数值越小,越优先
·
【注意】:@Priority注解只能标注在方法或者类上,和@Bean一起不生效
·
也许有人会想起@Order注解,该注解不影响依赖注入,可以参考@Order注解文章介绍
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
String highestPriorityBeanName = null;
Integer highestPriority = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (beanInstance != null) {
// 循环遍历获取候选bean的@Priority(1)注解的优先级数值
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (highestPriorityBeanName != null) {
// 多个@Priority注解的候选bean,且优先级数值相等,抛异常
if (candidatePriority.equals(highestPriority)) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"Multiple beans found with the same priority ('" + highestPriority +
"') among candidates: " + candidates.keySet());
}
// 多个@Priority注解的候选bean,且优先级数值小的优先
else if (candidatePriority < highestPriority) {
// 高优先级的候选bean作为返回
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
else {
// 优先级匹配成功,作为待返回的候选beanName
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
}
}
return highestPriorityBeanName;
}
3.4. resolveMultipleBeans:
3.4.0. 栗子:
@Configuration
public class ConfigurationBean {
@Bean
public BeanService beanService1() {
return new BeanServiceImpl();
}
@Bean
@Order(1)
public BeanService beanService() {
BeanServiceImpl beanService = new BeanServiceImpl();
beanService.setName("zhangsan");
return beanService;
}
}
@Component
public class SetterBean {
@Autowired
private List<BeanService> list;
//@Autowired
//private Map<String,BeanService> map;
//@Autowired
//private BeanService[] array;
}
@Component
@Order(3)
public class BeanServicePriority implements BeanService {
private String name;
}
此方法是注入依赖bean的集合对象
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
... ... ...
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
... ... ...
}
通过核心方法findAutowireCandidates将依赖的bean获取符合注入的实例,封装到matchingBeans
·
通过类型转换器,将matchingBeans符合依赖注入的bean转换成对对应集合类型(Array、Collection、Map)
·
对转换后的集合进行排序(Map除外),与@Order、@Priority(x)注解有关,优先级值越小越先调用,可参考链接
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
... ... ...
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
// 会获取符合注入的bean实例,封装到matchingBeans
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 将matchingBeans的bean实例转化成List
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
// 存在多个bean时,调用排序,@Order注解有关,属性值越小越先调用执行
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
else if (Map.class == type) {
... ... ...
}
3.4.1. addCandidateEntry:
在findAutowireCandidates中,符合注入的候选bean会被通过getBean获取实例,封装返回
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 注入的属性是集合类型
if (descriptor instanceof MultiElementDescriptor) {
// 通过beanFactory.getBean(beanName)获取注入的实例
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
// 封装到candidates,封装的是候选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 {
// 注入的属性的单个bean,封装的是候选bean类型
candidates.put(candidateName, getType(candidateName));
}
}
3.4.2. 关于@Primary、@Order、@Priority(x)调用排序:
@Primary不参与调用排序,@Order、@Priority(x)优先级值越小,越优先调用;
·
优先级(值)相同,按默认的bean注册顺序来调用
`
没有优先级注解或者@Order不填优先级值,默认值为Integer.MAX_VALUE,即按默认的bean注册顺序来调用
·
【原理】:主要是matchingBeans是从注册的bean中获取的,即beanDefinitionNames;再针对matchingBeans作优先级排序
3.5. 小结:
如果待注入的属性是bean的集合类型(Array、Collection、Map):
- 根据属性类型获取候选bean,过滤autowireCandidate=false;@Qualifier不匹配的候选bean
- 根据候选bean的beanName,调用beanFactory.getBean(beanName)获取候选bean实例
- 封装到候选bean集合matchingBeans(key:beanName; value:候选bean实例)
- 通过类型转换器,转换成对应集合类型,再对集合(Map除外),进行调用排序(涉及@Order、@Priority(x))
如果待注入的属性是bean:
- 根据属性类型获取候选bean,过滤autowireCandidate=false;@Qualifier不匹配的候选bean
- 封装到候选bean集合matchingBeans(key:beanName; value:候选bean实例或实例类型)
- 经过过滤还有多个候选bean:
·
选取标注@Primary的候选bean为最优bean
没有@Primary则选取优先级最高的(Order、@Priority优先级越小优先级越高)作为最优bean
没有优先级注解@Order、@Priority,最后通过属性beanName去匹配候选Bean的beanName,匹配成功则作为最优bean,否则抛异常
·- 经过上述过滤,找到最优的候选bean
- 如果最优的候选bean在matchingBeans的value是bean的类型,则beanFactory.getBean(beanName)获取实例再返回,否则直接返回实例
到这里,我们也可以知道@Autowired默认是byType注入的
`
中间还依次经历autowireCandidate、@Qualifier、@Primary、@Priority的过滤
·
最后才byName注入