@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
@Inherited
表示支持被继承;
org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver
实现了依赖注入候选解析器接口org.springframework.beans.factory.support.AutowireCandidateResolver
,继承自org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver
,Spring默认使用它负责候选处理,专门用于解析
org.springframework.beans.factory.annotation.Qualifier
注解;
构造函数
public QualifierAnnotationAutowireCandidateResolver() {
// 默认支持@Qualifier和javax.inject.Qualifier
this.qualifierTypes.add(Qualifier.class);
try {
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
核心方法
/**
* bdHolder 候选Bean的定义信息
* descriptor 待自动注入的描述信息
*/
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 先经过父类判断,是否允许依赖注入、泛型匹配
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
// 满足父类要求后,再进行判断@Qualifier注解是否匹配
// 如果descriptor是Field,则获取Field上的注解
// 如果descriptor是MethodParameter,则获取方法参数上的注解
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
// 若是MethodParameter,则需要进一步判断方法参数所在方法上的@Qualifier注解是否匹配
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
// 进一步校验构造函数/void方法上@Qualifier注解是否匹配
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
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是否匹配@Qualifier注解
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)) {
// 存在@Qualifier元注解
foundMeta = true;
// 如果fallbackToMeta,说明当前@Qualifier注解匹配失败,且存在@Qualifier元注解
// 那么@Qualifier元注解必须有值可以进行后续校验,否则认为不匹配
// Only accept fallback match if @Qualifier annotation has a value...
// 或者@A标注了@Qualifier,@B标注了@A,当annotation为@B时,fallbackToMeta为false,此时进一步判断当前Bean是否匹配@A注解
// 只向上找一层,如果@C标注了@B,当annotation为@C时,则无法fallbackToMeta
// 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) {
// 如果fallbackToMeta且未找到匹配的元注解,则认为不匹配
return false;
}
}
}
// 成功遍历完待校验注解列表,则认为匹配成功
return true;
}
protected boolean isQualifier(Class<? extends Annotation> annotationType) {
// 遍历已注册的Qualifier注解
for (Class<? extends Annotation> qualifierType : this.qualifierTypes) {
// 待判断的注解匹配当前注解类型或者标注了当前注解,则认为属于Qualifier注解
if (annotationType.equals(qualifierType) || annotationType.isAnnotationPresent(qualifierType)) {
return true;
}
}
return false;
}
protected boolean checkQualifier(
BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
Class<? extends Annotation> type = annotation.annotationType();
RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
// Bean定义信息的qualifiers字段一般都为空
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
if (qualifier == null) {
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
}
// 优先使用qualifier(xml配置),若qualifier为空则尝试获取targetAnnotation
//
//
//
if (qualifier == null) {
// 尝试从Bean定义信息获取该类型的注解信息
// First, check annotation on qualified element, if any
Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
// Then, check annotation on factory method, if applicable
if (targetAnnotation == null) {
// 若注解信息不存在,则尝试从Bean的工厂方法中获取该类型的注解信息
targetAnnotation = getFactoryMethodAnnotation(bd, type);
}
if (targetAnnotation == null) {
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
if (dbd != null) {
targetAnnotation = getFactoryMethodAnnotation(dbd, type);
}
}
if (targetAnnotation == null) {
// 若注解信息不存在,则从本类上获取该类型的注解信息
// Look for matching annotation on the target class
if (getBeanFactory() != null) {
try {
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
if (beanType != null) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Not the usual case - simply forget about the type check...
}
}
if (targetAnnotation == null && bd.hasBeanClass()) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(bd.getBeanClass()), type);
}
}
// 注解存在,且匹配待校验注解,则认为匹配
if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
return true;
}
}
// 若注解不存在,或者未匹配,则匹配待校验注解的所有属性
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
if (attributes.isEmpty() && qualifier == null) {
// 待校验注解不存在属性,则认为不匹配,因为注解不存在
// If no attributes, the qualifier must be present
return false;
}
// 遍历待校验注解的属性
// @Qualifier注解只有value属性
// 但是标注了@Qualifier注解的自定义注解,可以拥有其它属性
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
// 属性名称
String attributeName = entry.getKey();
// 期望的属性值
Object expectedValue = entry.getValue();
Object actualValue = null;
// Check qualifier first
if (qualifier != null) {
// 从qualifier中获取属性值,若存在的话
actualValue = qualifier.getAttribute(attributeName);
}
if (actualValue == null) {
// 从Bean定义信息中获取属性值
// Fall back on bean definition attribute
actualValue = bd.getAttribute(attributeName);
}
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
// 若属性值不存在,则判断Bean的名称是否匹配属性value对应的值
// Fall back on bean name (or alias) match
continue;
}
if (actualValue == null && qualifier != null) {
// Fall back on default, but only if the qualifier is present
actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
}
if (actualValue != null) {
actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
}
if (!expectedValue.equals(actualValue)) {
return false;
}
}
// 成功遍历玩待校验注解的所有属性,则认为匹配成功
return true;
}
过滤多匹配值
@Configuration
public class DemoConfiguration {
// 过滤demo类别
@Qualifier(value = "demo")
@Autowired
private Demo demo;
// 默认demo类别
@Bean
public Demo demo() {
return new Demo("demo");
}
// 默认demo1类别
@Bean
public Demo demo1() {
return new Demo("demo1");
}
// 指定类别为为demo1
@Qualifier(value = "demo1")
@Bean
public Demo demo2() {
return new Demo("demo2");
}
static class Demo {
private String name;
public Demo(String name) {
this.name = name;
}
@Override
public String toString() {
return "Demo{" +
"name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DemoConfiguration.class);
DemoConfiguration bean = context.getBean(DemoConfiguration.class);
System.out.println(bean.demo);
}
}
指定类别过滤
@Configuration
public class DemoConfiguration {
// 过滤demo类别
@Qualifier(value = "demo")
@Autowired
private List<Demo> demos;
// 满足 (actualValue == null &&
// attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
// expectedValue instanceof String &&
// bdHolder.matchesName((String) expectedValue))
@Bean
public Demo demo() {
return new Demo("demo");
}
// 满足 (targetAnnotation != null && targetAnnotation.equals(annotation))
// 指定类别为demo
@Qualifier(value = "demo")
@Bean
public Demo demo1() {
return new Demo("demo1");
}
// 默认demo2类别
@Bean
public Demo demo2() {
return new Demo("demo2");
}
static class Demo {
private String name;
public Demo(String name) {
this.name = name;
}
@Override
public String toString() {
return "Demo{" +
"name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DemoConfiguration.class);
DemoConfiguration bean = context.getBean(DemoConfiguration.class);
System.out.println(bean.demos);
}
}
自定义类别注解过滤
@Configuration
public class DemoConfiguration {
// 过滤@DemoTag注解
@DemoTag
@Autowired
private List<Demo> demos;
@Bean
public Demo demo() {
return new Demo("demo");
}
// 指定@DemoTag注解
@DemoTag
@Bean
public Demo demo1() {
return new Demo("demo1");
}
// 指定@DemoTag注解
@DemoTag
@Bean
public Demo demo2() {
return new Demo("demo2");
}
static class Demo {
private String name;
public Demo(String name) {
this.name = name;
}
@Override
public String toString() {
return "Demo{" +
"name='" + name + '\'' +
'}';
}
}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
@interface DemoTag {
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(DemoConfiguration.class);
DemoConfiguration bean = context.getBean(DemoConfiguration.class);
System.out.println(bean.demos);
}
}