Spring 5.x 源码之旅-85Qualifier注解三

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】 

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

checkQualifier检查要候选bean定义是否有这个注解

这个方法其实就是检查候选的bean定义里有没有相关Qualifier注解,先检查下bean定义有没有添加type类型的全限定类型和短类名的AutowireCandidateQualifier对象,如果没有的话就看有没有设置type类型的AnnotatedElement对象,还没有的话就检查bean定义的工厂方法上有没有这个type注解,我们这个刚好在这上面,再没有的话就从bean装饰的定义中找注解,最后为空的话就从bean定义的目标类上去找。如果AutowireCandidateQualifier存在的话,就获取他的属性和type限定注解上的属性做匹配。最后返回是否找到或者是否匹配上。

    protected boolean checkQualifier(
    			BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
    
    		Class<? extends Annotation> type = annotation.annotationType();
    		RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
    
    		AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());//检查bean定义有没有这个type全限定类名的AutowireCandidateQualifier对象
    		if (qualifier == null) {
    			qualifier = bd.getQualifier(ClassUtils.getShortName(type));//没有的话看下有没短的类名的
    		}
    		if (qualifier == null) {
    			// First, check annotation on qualified element, if any
    			Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);//检查bean定义里是否设置了type类型的限定类
    			// Then, check annotation on factory method, if applicable
    			if (targetAnnotation == null) {
    				targetAnnotation = getFactoryMethodAnnotation(bd, type);//从工厂方法找是否有限定注解,这里frieds1的工厂方法上有Girl注解,所以得到了
    			}
    			if (targetAnnotation == null) {//从bean装饰的定义中找注解
    				RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
    				if (dbd != null) {
    					targetAnnotation = getFactoryMethodAnnotation(dbd, type);
    				}
    			}
    			if (targetAnnotation == null) {//为空的话就从bean定义的目标类上去找
    				// 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;
    		}
    		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) {
    				actualValue = qualifier.getAttribute(attributeName);
    			}
    			if (actualValue == null) {
    				// 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)) {
    				// 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;
    	}

checkQualifiers部分2

如果前面判断不是Qualifier注解的,就进行注解上的注解获取,然后继续判断是不是Qualifier注解的。

    	if (checkMeta) {//不是Qualifier直接的注解,就获取注解的注解,进行isQualifier判断
    				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 && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
    								!checkQualifier(bdHolder, metaAnn, typeConverter)) {
    							return false;//有Qualifier注解,不符合条件的就返回false
    						}
    					}
    				}
    				if (fallbackToMeta && !foundMeta) {//如果不是Qualifier直接,又没发现注解上有Qualifier注解就返回false
    					return false;
    				}
    			}

大致流程就是这样,主要是看bean定义中是否有AutowireCandidateQualifier对象,没有的话看是否设置了AnnotatedElement对象,从这个上面去找有没有限定注解,再找不到从bean定义的工厂方法上找注解,再不行就从bean定义的目标类上去找。有的话是否全限定名或者短类名和限定注解相同,相同的话获取属性值和限定注解的属性值匹配,匹配上表示就返回true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值