作用
自动装配的用于获取候选者与判断符合要求的策略接口。主要功能有:
1、使用@Value时获取value值。
2、判断当前依赖是否符合@Quelifiers的条件
主要实现与调用
主要实现为ContextAnnotationAutowireCandidateResolver
调用
在DefaultListableBeanFactory中有成员变量为AutowireCandidateResolver
并且在doResolveDependency方法中调用了getSuggestedValue方法
在isAutowireCandidate方法中resolver.isAutowireCandidate。
关于这部分代码的调用逻辑在BeanFactory的resolveDependency中可以查看
初始化
在使用springboot 时,使用的是AnnotationConfigApplicationContext上下文。而AnnotationConfigApplicationContext在初始化是创建的是ContextAnnotationAutowireCandidateResolver对象
继承关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-25jjzOtp-1622365531389)(http://note.youdao.com/yws/res/20700/1A2EE840069E4CB381229D2788A92A4A)]
忽略掉Aware继承关系后,其继承关系就是一个笔直的关系。下面详细讲解
AutowireCandidateResolver
接口,定义了自动装配的候选集相关接口,主要有
- isAutowireCandidate 判断当前bean定义是否符合候选集,在我们使用@Quelifiers注解时判断逻辑在这里。
- isRequired 判断当前依赖是否为必须
- hasQualifier 是否有筛选条件
- getSuggestedValue 获取@Value的值
SimpleAutowireCandidateResolver
接口的简单实现,基本没有复杂逻辑,不做解析
GenericTypeAwareAutowireCandidateResolver
//TODO 待解析
QualifierAnnotationAutowireCandidateResolver
关于注解的候选筛选
isAutowireCandidate
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//判断父类是否满足,关于类型的判断
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
//关于限定符的判断
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
//方法注解判断判断
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
我们看到最后都是调用了checkQualifiers 方法进行判断
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)) {
//判断是否符合qualifier注解要求
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
fallbackToMeta = true;
}
else {
checkMeta = false;
}
}
//判断注解上的注解情况
if (checkMeta) {
boolean foundMeta = false;
for (Annotation metaAnn : type.getAnnotations()) {
Class<? extends Annotation> metaType = metaAnn.annotationType();
if (isQualifier(metaType)) {
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise it is just a marker for a custom qualifier annotation.
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
}
}
}
if (fallbackToMeta && !foundMeta) {
return false;
}
}
}
return true;
}
其中我们看到核心代码为用isQualifier 方法判断是否为qualifier注解,并用checkQualifier 判断是否符合注解要求。继续跟进checkQualifier 方法
checkQualifier 代码有点多主要将一下大致逻辑:
- 当注入字段与注入目标都有qualifier注解时,两者名称相同则可以注入对象。
- 当注入目标没有qualifier注解时,注入字段的qualifier值与注入目标bean名称相同时可以主任。
getSuggestedValue
解决@Value值的获取
@Override
@Nullable
public Object getSuggestedValue(DependencyDescriptor descriptor) {
Object value = findValue(descriptor.getAnnotations());
if (value == null) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
value = findValue(methodParam.getMethodAnnotations());
}
}
return value;
}
我们可以看到最后使用findValue方法
@Nullable
protected Object findValue(Annotation[] annotationsToSearch) {
if (annotationsToSearch.length > 0) { // qualifier annotations have to be local
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
if (attr != null) {
return extractValue(attr);
}
}
return null;
}
其中成员变量:valueAnnotationType的值时@Value。当前方法就是获取@Value的值。