当前位置: 首页 > news >正文

@Autowired注解(二)

          本文主要测试了两种情况的依赖注入。分别是泛型以及配合@Qulifier注解的注入。

代码如下:

@Configuration
public class TestAutowired {public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestAutowired.class);DefaultListableBeanFactory factory = context.getDefaultListableBeanFactory();//1.解析泛型类型的依赖注入testGeneric(factory);//2.解析带有@Qualifier的依赖注入testQulifier(factory);}private static void testGeneric(DefaultListableBeanFactory factory) throws NoSuchFieldException {DependencyDescriptor descriptor = new DependencyDescriptor(Target.class.getDeclaredField("studentDao"), true);Class<?> type = descriptor.getDependencyType();ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();resolver.setBeanFactory(factory);for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, type)) {BeanDefinition definition = factory.getMergedBeanDefinition(name);if (resolver.isAutowireCandidate(new BeanDefinitionHolder(definition, name), descriptor)) {System.out.println(name);System.out.println(descriptor.resolveCandidate(name,type,factory));}}}private static void testQulifier(DefaultListableBeanFactory factory) throws NoSuchFieldException {DependencyDescriptor descriptor2 = new DependencyDescriptor(Target.class.getDeclaredField("service"), true);Class<?> type = descriptor2.getDependencyType();ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();resolver.setBeanFactory(factory);for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, type)) {BeanDefinition definition = factory.getMergedBeanDefinition(name);if (resolver.isAutowireCandidate(new BeanDefinitionHolder(definition, name), descriptor2)) {System.out.println(name);System.out.println(descriptor2.resolveCandidate(name,type,factory));}}}@Componentstatic class Target {@Autowired private Service[] serviceArray;@Autowired private List<Service> serviceList;@Autowiredprivate Dao<Student> studentDao;@Autowired @Qualifier("service2") private Service service;}interface Dao<T> {T get();}@Component("dao1")static class Student implements Dao<Student>{private String name;@Overridepublic Student get() {return new Student();}}@Component("dao2")static class Teacher implements Dao<Teacher>{private String name;@Overridepublic Teacher get() {return new Teacher();}}interface Service{}@Component("service1")static class Service1 implements Service{private String name;}@Component("service2")static class Service2 implements Service{private String name;}@Component("service3")static class Service3 implements Service{private String name;}}

一.解析泛型类型的依赖注入

       如果@Autowired注入的类是一个泛型,Spring该如何查找?有两个接口都实现了Dao。这个时候只能拿到泛型里面的类型去判断。下面模拟的是框架的实现思路。

  1. 创建目标字段的依赖描述符

DependencyDescriptor descriptor2 = new DependencyDescriptor(Target.class.getDeclaredField("service"), true);


2. 获取依赖类型
3. 配置自动装配候选解析器(ContextAnnotationAutowireCandidateResolver)
4. 遍历所有匹配类型的Bean定义,筛选出符合条件的自动装配候选类
5. 输出候选Bean的名称和实例

二.解析带有@Qualifier的依赖注入

       如果@Autowired注入的类是一个接口,又有三个类实现了该接口。只根据接口类型还是不能确定类,只能配合@Qualifier注解根据类的名字去确认。

        所以我们首先通过DependencyDescriptor创建对Target类中service字段的依赖描述,该字段被@Autowired和@Qualifier("service2")注解修饰。接着获取该字段的依赖类型(即Service接口),并配置ContextAnnotationAutowireCandidateResolver自动装配候选解析器。然后使用BeanFactoryUtils.beanNamesForTypeIncludingAncestors方法查找所有类型为Service的Bean名称,遍历这些Bean定义,通过解析器的isAutowireCandidate方法判断哪些Bean适合作为该依赖的候选者(由于@Qualifier注解的存在,只有名为"service2"的Bean会通过筛选)。最后输出选中的Bean名称以及通过resolveCandidate方法解析出的Bean实例。整个过程演示了Spring如何结合类型匹配和@Qualifier注解来精确解析和注入特定的Bean实例。


文章转载自:

http://12WAgQrO.rrpbz.cn
http://hg8ceKEh.rrpbz.cn
http://0i3jkXx8.rrpbz.cn
http://fy5oPmNr.rrpbz.cn
http://UREtLtEJ.rrpbz.cn
http://moeLQ8yO.rrpbz.cn
http://LDr6w0Cw.rrpbz.cn
http://eirtMCsW.rrpbz.cn
http://ZY2EVXBw.rrpbz.cn
http://mARdv1eJ.rrpbz.cn
http://nr0JQfZH.rrpbz.cn
http://KMW7Boch.rrpbz.cn
http://3A2Usg5H.rrpbz.cn
http://AkvOr1a8.rrpbz.cn
http://kijjUALo.rrpbz.cn
http://Kk9SUF0B.rrpbz.cn
http://5dPLa8yA.rrpbz.cn
http://fXVLZ5If.rrpbz.cn
http://3J5PXmbM.rrpbz.cn
http://oc43CJwA.rrpbz.cn
http://sEjWn9O2.rrpbz.cn
http://B7vc1f0u.rrpbz.cn
http://2OeEyJXo.rrpbz.cn
http://XK1CmnwN.rrpbz.cn
http://7AizaRe2.rrpbz.cn
http://8dP8rKwP.rrpbz.cn
http://Rl5uwH9G.rrpbz.cn
http://z7tmWvox.rrpbz.cn
http://imi4COQ1.rrpbz.cn
http://klKM56Pf.rrpbz.cn
http://www.dtcms.com/a/369547.html

相关文章:

  • Linux基础指令(入门必备2.0)
  • 打工人日报#20250905
  • 【Leetcode】高频SQL基础题--610.判断三角形
  • CLIP学习
  • docker重启redis报错:iptables failed
  • 一文教您学会Ubuntu安装python
  • Qoder 全面解析:三大模式与开发者实战指南
  • 新后端漏洞(上)- Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)
  • 快手Keye-VL 1.5开源128K上下文+0.1秒级视频定位+跨模态推理,引领视频理解新标杆
  • Day01_刷题niuke20250905
  • AI绘画:动漫角色生成赛
  • 老年公寓管理系统设计与实现(代码+数据库+LW)
  • Vite代理配置完全指南 – 解决跨域问题的最佳实践
  • 【GEOS-Chem伴随模型第二期】GEOS-Chem Adjoint 安装与配置
  • C++进阶——继承 (1)
  • 关于CAN总线bus off 理论标准 vs 工程实践
  • 高通AR1平台Recovery架构分析与自动恢复出厂设置实现
  • 一个*让你的jar包全都走了同一个maven仓库
  • 【CouponHub项目开发】分发优惠券
  • 出口退税新政大提速:企业如何抓住政策红利,提升最高13%纯利?
  • ZooKeeper vs Redis:分布式锁的实现与选型指南
  • 载流子寿命
  • nVisual从入门到精通—简介
  • 【STM32外设】DAC
  • SQL 常用 OVER() 窗口函数介绍
  • 【开题答辩全过程】以 在线教育系统为例,包含答辩的问题和答案
  • SQL基础与DDL
  • 嵌入式ARM64 基于RK3588原生SDK添加用户配置选项./build lunch debian
  • 基于w5500的stm32f103 实战项目
  • Python 算数运算练习题