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

@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://www.xdnf.cn/news/20229.html

相关文章:

  • 【CAN通信】AUTOSAR架构下TC3xx芯片是如何将一帧CAN报文接收上来的
  • Xsens解码人形机器人训练的语言
  • 如何通过AI进行数据资产梳理
  • 43这周打卡——生成手势图像 (可控制生成)
  • 球坐标系下调和函数的构造:多项式边界条件的求解方法
  • linux Nginx服务配置介绍,和配置流程
  • 快手Keye-VL 1.5开源128K上下文+0.1秒级视频定位+跨模态推理,引领视频理解新标杆
  • 错误是ModuleNotFoundError: No module named ‘pip‘解决“找不到 pip”
  • vsan default storage policy 具体是什么策略?
  • HTB GoodGames
  • centos下gdb调试python的core文件
  • 串口通信的学习
  • 日内5%,总回撤10%:EagleTrader风控规则里,隐藏着什么核心考点?
  • 使用API接口获取淘宝商品详情数据需要注意哪些风险?
  • MySQL数据库精研之旅第十六期:深度拆解事务核心(上)
  • python + Flask模块学习 1 基础用法
  • IC ATE集成电路测试学习——Stuck-at fault And Chain(一)
  • 场景切换 × 流畅过渡动画实现方案 | 图扑软件
  • 老师如何高效收集学生学籍信息,完成收集工作?
  • 大模型赋能电子制造全生命周期质量管理的应用及实践
  • 个人健康管理系统设计与实现
  • 代码随想录算法训练营第三天| 链表理论基础 203.移除链表元素 707.设计链表 206.反转链表
  • react antd mobile表单时间选择器
  • 系统架构思考20241204
  • 问卷系统测试报告
  • latex公式符号与字体
  • 【Lin通信】AUTOSAR架构下TC3xx芯片Lin报文收发详解
  • AI提示词增强丨用EARS语法进行产品原子化拆解
  • 【Redis】初识 Redis 与基础数据结构
  • 设置静态IP的方法