Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >@Qualifier高级应用---按类别批量依赖注入(QualifierAnnotationAutowireCandidateResolver原理详解)【享学Spring】

@Qualifier高级应用---按类别批量依赖注入(QualifierAnnotationAutowireCandidateResolver原理详解)【享学Spring】

作者头像
YourBatman
发布于 2019-09-18 06:53:49
发布于 2019-09-18 06:53:49
1.4K00
代码可运行
举报
文章被收录于专栏:BAT的乌托邦BAT的乌托邦
运行总次数:0
代码可运行

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/f641385712/article/details/100890879

每篇一句

罗斯:选秀状元可能有水货,但MVP绝对没有

前言

上篇文章(讲解@LoadBalanced负载均衡)的末尾,我抛出了一个很重要的问题,建议小伙伴自己深入思考一番;本文主要针对此问题,作出一个统一的答复和讲解。 由于本人觉得这块知识点它属于Spring Framework的核心内容之一,非常的重要,因此单拎出来作专文讲述,希望对你有所帮助。

背景案例

说到@Qualifier这个注解大家并不陌生:它用于“精确匹配”Bean,一般用于同一类型的Bean有多个不同实例的case下,可通过此注解来做鉴别和匹配。 本以为@Qualifier注解使用在属性上、类上用于鉴别就够了,直到我看到LoadBalancerAutoConfiguration里有这么应用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@LoadBalanced
@Autowired(required = false)
private List<RestTemplate> restTemplates = Collections.emptyList();	

它能把容器内所有RestTemplate类型并且标注有@LoadBalanced注解的Bean全注入进来。 这个用法让我非常的惊喜,它给我提供额外一条思路,让我的框架多了一种玩法。为了融汇贯通它,使用起来尽量避免不采坑,那就只能揭开它,从底层原理处理解它的用法了。


QualifierAnnotationAutowireCandidateResolver详解

它是依赖注入候选处理器接口AutowireCandidateResolver的实现类,继承自GenericTypeAwareAutowireCandidateResolver,所以此类是功能最全、最为强大的一个处理器(ContextAnnotationAutowireCandidateResolver除外~),Spring内默认使用它进行候选处理。

它几乎可以被称为@Qualifier注解的"实现类",专门用于解析此注解。 带着上面的疑问进行原理分析如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// @since 2.5
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
	// 是个List,可以知道它不仅仅只支持org.springframework.beans.factory.annotation.Qualifier
	private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<>(2);
	private Class<? extends Annotation> valueAnnotationType = Value.class;


	// 空构造:默认支持的是@Qualifier以及JSR330标准的@Qualifier
	public QualifierAnnotationAutowireCandidateResolver() {
		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.
		}
	}
	
	// 非空构造:可自己额外指定注解类型
	// 注意:如果通过构造函数指定qualifierType,上面两种就不支持了,因此不建议使用
	// 而建议使用它提供的addQualifierType() 来添加~~~
	public QualifierAnnotationAutowireCandidateResolver(Class<? extends Annotation> qualifierType) {
	... // 省略add/set方法	

	// 这是个最重要的接口方法~~~  判断所提供的Bean-->BeanDefinitionHolder 是否是候选的
	// (返回true表示此Bean符合条件)
	@Override
	public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
		// 1、先看父类:ean定义是否允许依赖注入、泛型类型是否匹配
		boolean match = super.isAutowireCandidate(bdHolder, descriptor);
		// 2、若都满足就继续判断@Qualifier注解~~~~
		if (match) {
			// 3、看看标注的@Qualifier注解和候选Bean是否匹配~~~(本处的核心逻辑)
			// descriptor 一般封装的是属性写方法的参数,即方法参数上的注解
			match = checkQualifiers(bdHolder, descriptor.getAnnotations());
			// 4、若Field/方法参数匹配,会继续去看看参数所在的方法Method的情况
			// 若是构造函数/返回void。 进一步校验标注在构造函数/方法上的@Qualifier限定符是否匹配
		if (match) {
				MethodParameter methodParam = descriptor.getMethodParameter();
				// 若是Field,methodParam就是null  所以这里是需要判空的
				if (methodParam != null) {
					Method method = methodParam.getMethod();
					// method == null表示构造函数 void.class表示方法返回void
					if (method == null || void.class == method.getReturnType()) {
						// 注意methodParam.getMethodAnnotations()方法是可能返回空的
						// 毕竟构造方法/普通方法上不一定会标注@Qualifier等注解呀~~~~
						// 同时警示我们:方法上的@Qualifier注解可不要乱标
						match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
					}
				}
			}
		}
		return match;
	}
	...
}

在源码注释的地方,我按照步骤标出了它进行匹配的一个执行步骤逻辑。需要注意如下几点:

  • qualifierTypes是支持调用者自己指定的(默认只支持@Qualifier类型)
  • 只有类型匹配、Bean定义匹配、泛型匹配等全部Ok了,才会使用@Qualifier去更加精确的匹配
  • descriptor.getAnnotations()的逻辑是: - 如果DependencyDescriptor描述的是字段(Field),那就去字段里拿注解们 - 若描述的是方法参数(MethodParameter),那就返回的是方法参数的注解
  • 步骤3的match = true表示Field/方法参数上的限定符是匹配的~

说明:能走到isAutowireCandidate()方法里来,那它肯定是标注了@Autowired注解的(才能被AutowiredAnnotationBeanPostProcessor后置处理),所以descriptor.getAnnotations()返回的数组长度至少为1

checkQualifiers()方法:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QualifierAnnotationAutowireCandidateResolver:

	// 将给定的限定符注释与候选bean定义匹配。命名中你发现:这里是负数形式,表示多个注解一起匹配
	// 此处指的限定符,显然默认情况下只有@Qualifier注解
	protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
		// 很多人疑问为何没标注注解返回的还是true?
		// 请参照上面我的解释:methodParam.getMethodAnnotations()方法是可能返回空的,so...可以理解了吧
		if (ObjectUtils.isEmpty(annotationsToSearch)) {
			return true;
		}
		SimpleTypeConverter typeConverter = new SimpleTypeConverter();

		// 遍历每个注解(一般有@Autowired+@Qualifier两个注解)
		// 本文示例的两个注解:@Autowired+@LoadBalanced两个注解~~~(@LoadBalanced上标注有@Qualifier)
		for (Annotation annotation : annotationsToSearch) {
			Class<? extends Annotation> type = annotation.annotationType();
			boolean checkMeta = true; // 是否去检查元注解
			boolean fallbackToMeta = false;

			// isQualifier方法逻辑见下面:是否是限定注解(默认的/开发自己指定的)
			// 本文的org.springframework.cloud.client.loadbalancer.LoadBalanced是返回true的
			if (isQualifier(type)) {
				// checkQualifier:检查当前的注解限定符是否匹配
				if (!checkQualifier(bdHolder, annotation, typeConverter)) {
					fallbackToMeta = true; // 没匹配上。那就fallback到Meta去吧
				} else {
					checkMeta = false; // 匹配上了,就没必要校验元数据了喽~~~
				}
			}

			// 开始检查元数据(如果上面匹配上了,就不需要检查元数据了)
			// 比如说@Autowired注解/其它自定义的注解(反正就是未匹配上的),就会进来一个个检查元数据
			// 什么时候会到checkMeta里来:如@A上标注有@Qualifier。@B上标注有@A。这个时候限定符是@B的话会fallback过来
			if (checkMeta) {
				boolean foundMeta = false;
				// type.getAnnotations()结果为元注解们:@Documented、@Retention、@Target等等
				for (Annotation metaAnn : type.getAnnotations()) {
					Class<? extends Annotation> metaType = metaAnn.annotationType();
					if (isQualifier(metaType)) {
						foundMeta = true; // 只要进来了 就标注找到了,标记为true表示从元注解中找到了
						// Only accept fallback match if @Qualifier annotation has a value...
						// Otherwise it is just a marker for a custom qualifier annotation.
						// fallback=true(是限定符但是没匹配上才为true)但没有valeu值
						// 或者根本就没有匹配上,那不好意思,直接return false~
						if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) || !checkQualifier(bdHolder, metaAnn, typeConverter)) {
							return false;
						}
					}
				}
				// fallbackToMeta =true你都没有找到匹配的,就返回false的
				if (fallbackToMeta && !foundMeta) {
					return false;
				}
			}
		}
		// 相当于:只有所有的注解都木有返回false,才会认为这个Bean是合法的~~~
		return true;
	}

	// 判断一个类型是否是限定注解   qualifierTypes:表示我所有支持的限定符
	// 本文的关键在于下面这个判断语句:类型就是限定符的类型 or @Qualifier标注在了此注解上(isAnnotationPresent)
	protected boolean isQualifier(Class<? extends Annotation> annotationType) {
		for (Class<? extends Annotation> qualifierType : this.qualifierTypes) {
			// 类型就是限定符的类型 or @Qualifier标注在了此注解上(isAnnotationPresent)
			if (annotationType.equals(qualifierType) || annotationType.isAnnotationPresent(qualifierType)) {
				return true;
			}
		}
		return false;
	}

checkQualifiers()方法它会检查标注的所有的注解(循环遍历一个个检查),规则如下:

  • 若是限定符注解(自己就是@Qualifier或者isAnnotationPresent),匹配上了,就继续看下一个注解 - 也就说@Qualifier所标注的注解也算是限定符(isQualifier() = true)
  • 若是限定符注解但是没匹配上,那就fallback。继续看看标注在它身上的限定符注解(如果有)能否匹配上,若匹配上了也成
  • 若不是限定符注解,也是走fallback逻辑
  • 总之:若不是限定符注解直接忽略。若有多个限定符注解都生效,必须全部匹配上了,才算做最终匹配上。

Tips:限定符不生效的效果不一定是注入失败,而是如果是单个的话还是注入成功的。只是若出现多个Bean它就无法起到区分的效果了,所以才会注入失败了~

它的fallback策略最多只能再向上再找一个层级(多了就不行了)。例如上例子中使用@B标注也是能起到@Qualifier效果的,但是若再加一个@C层级,限定符就不生效了。

注意:Class.isAnnotationPresent(Class<? extends Annotation> annotationClass)表示annotationClass是否标注在此类型上(此类型可以是任意Class类型)。 此方法不具有传递性:比如注解A上标注有@Qualifier,注解B上标注有@A注解,那么你用此方法判断@B上是否有@Qualifier它是返回false的(即使都写了@Inherited注解,因为和它没关系)

到这其实还是不能解释本文中为何@LoadBalanced参与了依赖注入,还得继续看精髓中的精髓checkQualifier()方法(方法名是单数,表示精确检查某一个单独的注解):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QualifierAnnotationAutowireCandidateResolver:

	// 检查某一个注解限定符,是否匹配当前的Bean
	protected boolean checkQualifier(BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
		// type:注解类型 bd:当前Bean的RootBeanDefinition 
		Class<? extends Annotation> type = annotation.annotationType();		
		RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
	
		// ========下面是匹配的关键步骤=========
		// 1、Bean定义信息的qualifiers字段一般都无值了(XML时代的配置除外)
		// 长名称不行再拿短名称去试了一把。显然此处 qualifier还是为null的
		AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
		if (qualifier == null) {
			qualifier = bd.getQualifier(ClassUtils.getShortName(type));
		}
		
		//这里才是真真有料的地方~~~请认真看步骤
		if (qualifier == null) {
			// First, check annotation on qualified element, if any
			// 1、词方法是从bd标签里拿这个类型的注解声明,非XML配置时代此处targetAnnotation 为null
			Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
			// Then, check annotation on factory method, if applicable
			// 2、若为null。去工厂方法里拿这个类型的注解。这方法里标注了两个注解@Bean和@LoadBalanced,所以此时targetAnnotation就不再为null了~~
			if (targetAnnotation == null) {
				targetAnnotation = getFactoryMethodAnnotation(bd, type);
			}

			// 若本类木有,还会去父类去找一趟
			if (targetAnnotation == null) {
				RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
				if (dbd != null) {
					targetAnnotation = getFactoryMethodAnnotation(dbd, type);
				}
			}


			// 若xml、工厂方法、父里都还没找到此方法。那好家伙,回退到还去类本身上去看
			// 也就是说,如果@LoadBalanced标注在RestTemplate上,也是阔仪的
			if (targetAnnotation == null) {
				// Look for matching annotation on the target class
				...
			}
		
			// 找到了,并且当且仅当就是这个注解的时候,就return true了~
			// Tips:这里使用的是equals,所以即使目标的和Bean都标注了@Qualifier属性,value值相同才行哟~~~~
			// 简单的说:只有value值相同,才会被选中的。否则这个Bean就是不符合条件的
			if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
				return true;
			}
		}

		// 赞。若targetAnnotation还没找到,也就是还没匹配上。仍旧还不放弃,拿到当前这个注解的所有注解属性继续尝试匹配
		Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
		if (attributes.isEmpty() && qualifier == null) {
			return false;
		}
		... // 详情不描述了。这就是为什么我们吧@Qualifier标注在某个类上面都能生效的原因 就是这里做了非常强大的兼容性~
	}

// =================它最重要的两个判断=================
if (targetAnnotation != null && targetAnnotation.equals(annotation));

// Fall back on bean name (or alias) match
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
					expectedValue instanceof String && bdHolder.matchesName((String) expectedValue));

checkQualifier()方法的实现,足以看到Spring作为一个优秀框架它对case的全面性,兼容性、灵活性的考虑还是很到位的。正因为Spring提供的强大的支持和灵活扩展,才给与了SpringBoot、SpringCloud在框架层面设计上更多可能性~




@Qualifier高级使用

@Autowired是根据类型进行自动装配的,当Spring容器内同一类型的Bean不止一个的时候,就需要借助@Qualifier来一起使用了。

示例一:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class WebMvcConfiguration {

    @Qualifier("person1")
    @Autowired
    public Person person;

    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }
}

单测代码如下(下同):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(WebMvcConfiguration.class);
    WebMvcConfiguration bean = context.getBean(WebMvcConfiguration.class);
    // 打印字段的值
    System.out.println(bean.person);

}

运行后打印Person(name=fsx01, age=16),完全符合预期。这也是我们对@Qualifier注解最常规、最简单的使用。

示例二:

若你细心的话你可能注意到了@Qualifier注解它允许继承(@Inherited)、能标注在字段上、方法上、方法参数、类上、注解上。 因此它还能这么用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class WebMvcConfiguration {

    @MyAnno // 会把所有标注有此注解的Bean都收入囊中,请List装(因为会有多个)
    @Autowired
    public List<Person> person;
    
    @MyAnno
    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }
    @MyAnno
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }

	// 自定义注解:上面标注有@Qualifier注解
    @Target({FIELD, METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    @interface MyAnno {
    }
}

运行单测,打印[Person(name=fsx01, age=16), Person(name=fsx02, age=18)],符合预期。

实例三:

若你不想自定义注解,直接使用@Qualifier注解分类注入也是可以的,如下案例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class WebMvcConfiguration {
    @Qualifier("person2")
    @Autowired
    public List<Person> person;

    @Qualifier("person2")
    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }

    @Qualifier
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }
    @Qualifier
    @Bean
    public Person person3() {
        return new Person("fsx03", 20);
    }
}

运行的最终结果是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Person(name=fsx01, age=16), Person(name=fsx02, age=18)]

它把@Qualifier指定的value值相同的 或者 beanName(或者别名)相同的都注入进来了。这部分匹配代码为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
checkQualifier方法:

1、头上标注的注解完全equals(类型和value值都一样,算作匹配成功)
	targetAnnotation != null && targetAnnotation.equals(annotation)
	
2、Fall back on bean name (or alias) match。若@Qualifier没匹配上,回退到BeanName的匹配,规则为:
   取头上注解的`value`属性(必须有此属性),如果beanName/alias能匹配上次名称,也算最终匹配成功了
   
	actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
	expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)

备注:使用在类上、入参上的使用比较简单,此处就不做示范了。 从@Qualifier设计的细节可以看到,注解的value属性并不是必须的,所以它可以很好的使用在联合注解的场景。

关于依赖注入和@Qualifier的使用亦需注意如下细节:

  1. @Autowired可不要写在Object类型的字段上去注入,因为容器内可以找到N多个会报错的。但是List<Object>是可以的(相当于把所有Bean都拿过来~)
  2. 可以利用@Qualifier这个高级特性,实现按需、按类别(不是类型)进行依赖注入,这种能力非常赞,给了框架二次开发设计者提供了更多的可能性

如果说指定value是按照key进行限定/匹配,那么类似@LoadBalanced这种注解匹配可以理解成就是按照莫一类进行归类限定了,并且自由度也更高了。

总结

本文介绍@Qualifier高级应用场景和案例,通过结合@LoadBalanced对此注解的使用,应该说是能给你打开了一个新的视角去看待@Qualifier,甚至看待Spring的依赖注入,这对后续的理解、自定义扩展/使用还是蛮有意义的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年09月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring 中 @Qualifier 注解还能这么用?
今天想和小伙伴们聊一聊 @Qualifier 注解的完整用法,同时也顺便分析一下它的实现原理。
江南一点雨
2023/09/09
1K0
Spring 中 @Qualifier 注解还能这么用?
从源码中看@Qualifier注解
@Qualifier注解通常和@Autowired注解一起使用,那么首先来看@Autowire是怎么把Bean对象注入到Spring容器中的。
关忆北.
2023/11/06
2270
从源码中看@Qualifier注解
Spring依赖注入(DI)核心接口AutowireCandidateResolver深度分析,解析@Lazy、@Qualifier注解的原理【享学Spring】
关于AutowireCandidateResolver接口,可能绝大多数小伙伴都会觉得陌生。但若谈起@Autowired、@Primary、@Qualifier、@Value、@Lazy等注解,相信没有小伙伴是不知道的吧。
YourBatman
2019/09/03
1.3K0
Spring依赖注入(DI)核心接口AutowireCandidateResolver深度分析,解析@Lazy、@Qualifier注解的原理【享学Spring】
【小家Spring】细说Spring IOC容器的自动装配(@Autowired),以及Spring4.0新特性之【泛型依赖注入】的源码级解析
前面我发布了Spring IOC容器的刷新(初始化)过程,以及Spring 容器的Bean的实例化、初始化过程。其中有一个步骤小伙伴们比较关心,也提问的比较多,那就是泛型依赖注入。鉴于之前对这一块描述得也不是很详细,鉴于此处还是比较重要的,因此本文专门用篇幅聊聊这个事
YourBatman
2019/09/03
3.8K0
【小家Spring】细说Spring IOC容器的自动装配(@Autowired),以及Spring4.0新特性之【泛型依赖注入】的源码级解析
Spring杂谈 | Spring中的AutowireCandidateResolver
接口定义 用于推断一个特定的beanDefinition是否能作为指定依赖的候选者的策略接口 ” public interface AutowireCandidateResolver { // 默认情况下直接根据bd中的定义返回,如果没有进行特殊配置的话为true default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { return bdHolder
程序员DMZ
2020/07/06
6930
源码剖析Spring依赖注入:今天你还不会,你就输了
在之前的讲解中,我乐意将源码拿出来并粘贴在文章中,让大家看一下。然而,我最近意识到这样做不仅会占用很多篇幅,而且实际作用很小,因为大部分人不会花太多时间去阅读源码。
努力的小雨
2024/02/06
3120
Spring依赖注入@Autowired深层原理、源码级分析,感受DI带来的编程之美【享学Spring】
关于Spring IOC的依赖注入(DI机制),之前虽有过分析,但总感觉一直落了一块:对@Autowired注解元数据的解析部分。
YourBatman
2019/09/03
2.1K2
Spring依赖注入@Autowired深层原理、源码级分析,感受DI带来的编程之美【享学Spring】
【小家Spring】Spring标准处理组件大合集(ParameterNameDiscoverer、AutowireCandidateResolver、ResolvableType。。。)
本篇博文更像是一个工具文章,在阅读Spring源码的时候,经常会遇见一些处理器、提供器之类的组件,有的时候不深入去理解它的含义,确实还读不下去了。
YourBatman
2019/09/03
2K0
【小家Spring】Spring标准处理组件大合集(ParameterNameDiscoverer、AutowireCandidateResolver、ResolvableType。。。)
spring源码篇(四)依赖注入(控制反转)
​ 上一篇走了一遍bean的生成过程,也是spring容器启动的一个重要过程,而在这个过程中,有一个属性填充的步骤,也就是依赖注入,这个概念不难,但其底层实现其实却有很多复杂的步骤,使得这个依赖注入的功能比较强大,所以这篇就是从源码角度,了解spring的依赖注入功能。
用针戳左手中指指头
2021/03/22
7400
Spring源码解析(七):bean后置处理器AutowiredAnnotationBeanPostProcessor
冬天vs不冷
2025/01/21
2270
Spring源码解析(七):bean后置处理器AutowiredAnnotationBeanPostProcessor
【小家Spring】Spring贡献的多个注解相关的工具类:AnnotationUtils、AnnotatedElementUtils、AnnotationConfigUtils...
本文主要聊聊Spring提供的多个关于注解相关的工具类:AnnotationUtils和AnnotatedElementUtils等等 因为很多逻辑都封装在了工具类里面,因此要理解Spring的深层意思,有时候不了解工具类也是比较麻烦的
YourBatman
2019/09/03
3.7K0
【小家Spring】Spring贡献的多个注解相关的工具类:AnnotationUtils、AnnotatedElementUtils、AnnotationConfigUtils...
Spring源码学习:一篇搞懂@Autowire和@Resource注解的区别
最近在刷到很多文章讲解Spring IOC依赖注入时@Autowire和@Resource注解的区别,不同的文章总结出来的点有异同,所以还是看源码自己总结一下其两者的区别,及其用法。
@猪大肠
2023/02/16
2.1K0
Spring源码学习:一篇搞懂@Autowire和@Resource注解的区别
Spring Boot2.x-05Spring Boot基础-使用注解完成依赖注入
Spring Boot2.x-04Spring Boot基础-使用注解装配bean 中讲了如何将Bean装载到IoC容器中,这里我们说下Bean之间的依赖关系,当然了还是基于注解的方式。
小小工匠
2021/08/17
4170
Spring6框架中依赖注入的多种方式(推荐构造器注入)
一个典型的企业应用程序不是由单个对象(或在Spring术语中称为bean)组成的。
codetrend
2024/05/26
3550
《Spring实战》读书笔记-第3章 高级装配
《Spring实战》是学习Spring框架的一本非常经典的书籍,之前阅读了这本书,只是在书本上写写画画,最近整理了一下《Spring实战》的读书笔记,通过博客的方式进行记录分享。俗话说,好记性不如烂笔头,把学习到的知识记录下来,方便温故知新,让更多的读者可以学习到有关Spring框架的知识。
Java架构师必看
2020/04/10
6870
【小家Spring】Spring AOP核心类Pointcut解析,对PointcutExpression切点表达式解析原理分析(以AspectJExpressionPointcut为例)
首先需要说明一点:Pointcut接口有两个。 一个是:org.aspectj.lang.reflect.Pointcut,它是aspectj内部使用的。它只有一个实现类PointcutImpl。是它内部的抽象 另一个是:org.springframework.aop.Pointcut,这是Spring AOP体系中对切点的顶层抽象,贯穿整个AOP过程,非常重要。因此本文主要基于它,介绍一些原理以及它常用子类的一些使用。
YourBatman
2019/09/03
4.5K1
【小家Spring】Spring AOP核心类Pointcut解析,对PointcutExpression切点表达式解析原理分析(以AspectJExpressionPointcut为例)
Spring的@Autowired依赖注入原来这么多坑!
经常会遇到,required a single bean, but 2 were found。
JavaEdge
2021/12/07
6600
Spring的@Autowired依赖注入原来这么多坑!
Spring框架参考手册_5.0.0_中英文对照版_Part II_3.9
An alternative to XML setups is provided by annotation-based configuration which rely on the bytecode metadata for wiring up components instead of angle-bracket declarations. Instead of using XML to describe a bean wiring, the developer moves the configuration into the component class itself by using annotations on the relevant class, method, or field declaration. As mentioned in the section called “Example: The RequiredAnnotationBeanPostProcessor”, using a BeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container. For example, Spring 2.0 introduced the possibility of enforcing required properties with the @Required annotation. Spring 2.5 made it possible to follow that same general approach to drive Spring’s dependency injection. Essentially, the @Autowired annotation provides the same capabilities as described in Section 3.4.5, “Autowiring collaborators” but with more fine-grained control and wider applicability. Spring 2.5 also added support for JSR-250 annotations such as @PostConstruct, and @PreDestroy. Spring 3.0 added support for JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as @Inject and @Named. Details about those annotations can be found in the relevant section.
Tyan
2019/05/25
1.3K0
Spring学习笔记(2)一DI依赖注入和Spring Bean配置、注解原理、动态注入
Spring容器是Spring框架的核心。容器将创建对象,它们连接在一起,配置它们,并从创建到销毁管理他们的整个生命周期。在Spring容器使用依赖注入(DI)来管理组成应用程序的组件。这些对象被称为Spring Beans。 IOC(Inversion of Control):传统的方法,当某个java对象A需要调用对象B时,是由调用者(对象A)通过new关键字来创建对象B的,而在Spring中,则是由spring完成创建的,所以“控制反转”了。Spring通过一种称作控制反转(IoC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI(JNDI是 Java 命名与目录接口Java Naming and Directory Interface))相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。 DI(Dependency Injection)—IOC的另一种表述方式:即组件以一些预先定义好的方式(例如: setter方法)接受来自如容器的资源注入.相对于 IOC而言,这种表述更直接。
黄规速
2022/04/14
8440
Spring学习笔记(2)一DI依赖注入和Spring Bean配置、注解原理、动态注入
【小家Spring】Spring中@Value注解有多强大?从原理层面去剖析为何它有如此大的“能耐“
@Value注解是Spring3.0后提出来的一个注解。注解内容本身非常之简单,但是它提供的功能却非常之强大。
YourBatman
2019/09/03
5.3K0
【小家Spring】Spring中@Value注解有多强大?从原理层面去剖析为何它有如此大的“能耐“
推荐阅读
Spring 中 @Qualifier 注解还能这么用?
1K0
从源码中看@Qualifier注解
2270
Spring依赖注入(DI)核心接口AutowireCandidateResolver深度分析,解析@Lazy、@Qualifier注解的原理【享学Spring】
1.3K0
【小家Spring】细说Spring IOC容器的自动装配(@Autowired),以及Spring4.0新特性之【泛型依赖注入】的源码级解析
3.8K0
Spring杂谈 | Spring中的AutowireCandidateResolver
6930
源码剖析Spring依赖注入:今天你还不会,你就输了
3120
Spring依赖注入@Autowired深层原理、源码级分析,感受DI带来的编程之美【享学Spring】
2.1K2
【小家Spring】Spring标准处理组件大合集(ParameterNameDiscoverer、AutowireCandidateResolver、ResolvableType。。。)
2K0
spring源码篇(四)依赖注入(控制反转)
7400
Spring源码解析(七):bean后置处理器AutowiredAnnotationBeanPostProcessor
2270
【小家Spring】Spring贡献的多个注解相关的工具类:AnnotationUtils、AnnotatedElementUtils、AnnotationConfigUtils...
3.7K0
Spring源码学习:一篇搞懂@Autowire和@Resource注解的区别
2.1K0
Spring Boot2.x-05Spring Boot基础-使用注解完成依赖注入
4170
Spring6框架中依赖注入的多种方式(推荐构造器注入)
3550
《Spring实战》读书笔记-第3章 高级装配
6870
【小家Spring】Spring AOP核心类Pointcut解析,对PointcutExpression切点表达式解析原理分析(以AspectJExpressionPointcut为例)
4.5K1
Spring的@Autowired依赖注入原来这么多坑!
6600
Spring框架参考手册_5.0.0_中英文对照版_Part II_3.9
1.3K0
Spring学习笔记(2)一DI依赖注入和Spring Bean配置、注解原理、动态注入
8440
【小家Spring】Spring中@Value注解有多强大?从原理层面去剖析为何它有如此大的“能耐“
5.3K0
相关推荐
Spring 中 @Qualifier 注解还能这么用?
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验