从零开始 Spring Boot 43:DI 注解

news2024/10/6 8:35:03

从零开始 Spring Boot 43:DI 注解

spring boot

图源:简书 (jianshu.com)

Spring 通过注解实现 DI(依赖注入),本文详细讨论这些注解。

@Autowired

@Autowired是 Spring 定义的注解,属于包org.springframework.beans.factory.annotation

@Autowired匹配 bean 的顺序是:

  1. 按类型(type)匹配
  2. 按限定符(qualifier)匹配
  3. 按名称(name)匹配

@Autowired是最常用的注解,用它可以通过属性注入、Setter注入、构造器注入来实现DI。在前文中讨论过这些内容,这里不再重复。

筛选备选项

一般来说,用@Autowired注入时必须存在类型匹配的唯一的 bean,没有匹配到和匹配到一个以上的 bean 都会报错:

@ToString
@EqualsAndHashCode
public abstract class Carrier {
    protected final String maker;
    protected final String model;

    protected Carrier(String maker, String model) {
        this.maker = maker;
        this.model = model;
    }
}

@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Car extends Carrier {
    public Car(final String maker, final String model) {
        super(maker, model);
    }
}

@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Motorcycle extends Carrier {
    public Motorcycle(final String maker, final String model) {
        super(maker, model);
    }
}

@Service
public class CarrierService {
    @Autowired
    private Carrier defaultCarrier;

    public Carrier getDefaultCarrier() {
        return defaultCarrier;
    }
}

@Configuration
public class WebConfig {
    @Lazy
    @Autowired
    private CarrierService carrierService;

    @Bean
    Car defaultCar(){
        return new Car("长安汽车","X5");
    }

    @Bean
    Motorcycle defaultMotorcycle(){
        return new Motorcycle("哈雷","A7");
    }

    @Bean
    ApplicationRunner applicationRunner(){
        return args -> {
            Carrier defaultCarrier = carrierService.getDefaultCarrier();
            System.out.println(defaultCarrier);
        };
    }
}

这里定义的两个 bean 都具备Carrier类型,因此用@Autowired注入Carrier defaultCarrier属性时会报错,Spring 不知道要注入的是哪一个。

可以通过@Qualifier缩小筛选范围:

@Service
public class CarrierService {
    @Autowired
    @Qualifier("defaultCar")
    private Carrier defaultCarrier;
    // ...
}

示例中使用@Qualifier("defaultCar")将注入限定为名称为defaultCar的 bean,因此可以正常注入。

除了使用限定符,还可以使用名称进行筛选,@Autowired使用属性名作为 bean 名称进行匹配:

@Service
public class CarrierService {
    @Autowired
    private Carrier defaultCar;
    // ...
}

在用于名称匹配时,@Autowired并不好用,因为它只能用属性名作为 bean 名称匹配,@Resource则可以用name属性指定 bean 名称,而@inject可以使用@Named注解指定 bean 名称。

@Qualifier还可以更灵活地对 bean 进行筛选,详细内容可以阅读我的另一篇文章。

除了@Qualifier,还可以使用@Primary指定一个主要的 bean 作为有多个备选项时的首选注入,详细情况可以参考我的同一篇文章。

@Resource

@Resource是 Java 扩展包的注解,属于包javax.annotation.Resource

@Autowired按照类型优先进行匹配,@Resource按照名称优先进行匹配,其匹配顺序是:

  1. 按名称(name)匹配
  2. 按类型(type)匹配
  3. 按限定符(qualifier)匹配

修改之前的示例,使用@Resource进行依赖注入:

@Service
public class CarrierService {
    @Resource
    private Carrier defaultCarrier;
	// ...
}

会报错,因为不能按照defaultCarrier找到 bean,如果按照类型Carrier匹配,能匹配到2个。

可以通过@Resourcename属性指定要匹配的 bean 名称:

@Service
public class CarrierService {
    @Resource(name = "defaultCar")
    private Carrier defaultCarrier;
    // ...
}

或者也可以修改属性名称:

@Service
public class CarrierService {
    @Resource
    private Carrier defaultCar;

    public Carrier getDefaultCarrier() {
        return defaultCar;
    }
}

或者按照类型匹配,提供一个唯一 bean 对应的类型:

@Service
public class CarrierService {
    @Resource
    private Car defaultCarrier;
    // ...
}

最后,同样可以使用@Qualifier

@Service
public class CarrierService {
    @Resource
    @Qualifier("defaultCar")
    private Carrier defaultCarrier;
    // ...
}

@Resource还可以通过 Setter 注入,用法与属性注入一致,这里不再说明。

@Inject

@Inject同样属于 Java 扩展包,属于包javax.inject.Inject

@Inject的匹配顺序是:

  1. 按类型匹配
  2. 按限定符匹配
  3. 按名称匹配

要使用@Inject注解要先添加依赖:

<dependency>
    <groupId>jakarta.inject</groupId>
    <artifactId>jakarta.inject-api</artifactId>
    <version>2.0.1</version>
</dependency>

先看按类型匹配的示例:

@Service
public class CarrierService {
    @Inject
    private Car defaultCarrier;
	// ...
}

如果按类型匹配出多个候选项,可以通过限定符进一步匹配:

@Service
public class CarrierService {
    @Inject
    @Qualifier("defaultCar")
    private Carrier defaultCarrier;
	// ...
}

也可以通过名称进一步匹配:

@Service
public class CarrierService {
    @Inject
    @Named("defaultMotorcycle")
    private Carrier defaultCarrier;
	// ...
}

@Named同样属于 Java 扩展包,属于包jakarta.inject.Named

如果@Named注解没有起作用,可以检查一下 maven 依赖中的jakarta.inject模块的版本是否正确。

@Inject用于 Setter 注入的方式与属性注入类似,这里不再赘述。

@Inject也可以用于构造器注入:

@Service
public class CarrierService {
    private Carrier defaultCarrier;

    @Inject
    public CarrierService(@Named("defaultCar") Carrier defaultCarrier) {
        this.defaultCarrier = defaultCarrier;
    }
    // ...
}

总结

如果需要按照类型优先匹配,可以使用@Autowired@inject,如果需要按照 bean 名称优先匹配,可以使用@Resource

参考资料

  • 从零开始 Spring Boot 27:IoC - 红茶的个人站点 (icexmoon.cn)
  • Using JSR 330 Standard Annotations :: Spring Framework
  • Wiring in Spring: @Autowired, @Resource and @Inject | Baeldung

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/661839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【无标题】AI+电力、大模型主题人工智能师资培训班重磅招募中

大语言模型热度空前&#xff0c;诸如文心一言、ChatGPT 等已经能够与人对话互动、回答问题、协助创作&#xff0c;逐渐应用于人们的工作和生活&#xff0c;也引发了社会热议。人工智能赋能新型电力系统下新能源发电、变电、调度、配网、安监、营销、基建以及企业经营管理等领域…

强化学习从基础到进阶-案例与实践[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

MySQL数据库的高级操作

数据表高级操作 一、克隆表&#xff0c;将数据表的数据记录生成到新的表中方法一方法二 二、清空表&#xff0c;删除表内的所有数据方法一方法二 三、创建临时表四、创建外键约束&#xff0c;保证数据的完整性和一致性。1、外键的定义2、主键表和外键表的理解3、MySQL中6种常见…

盘点一个Python自动化办公案例分享

背景&#xff1a;某公司需要对某一款产品的销售情况进行跟踪和分析&#xff0c;分析需求包括必要的统计图表生成&#xff0c;数据分析&#xff0c;生成报告等操作。 解决方案&#xff1a;利用 Python 编写自动化程序&#xff0c;实现对该产品的销售数据自动抓取&#xff0c;数据…

【python+Coppeliasim】仓储机器人

一、仓储机器人介绍 仓储机器人&#xff08;也称为自动导航AGV&#xff0c;Automated Guided Vehicle&#xff09;是一种智能机器人系统&#xff0c;专门设计用于在仓库、物流中心和制造业等环境中执行货物搬运和物流任务。它们被广泛应用于自动化仓储和物流管理系统中&#xf…

详解HTTP协议和HTTPS协议

目录 一.HTTP协议 1.什么是HTTP 2.HTTP发展历史 3.HTTP请求和响应 4. 抓包的方式和工具Fiddler 1.开发者工具 2.Fiddler 二.请求和响应 1.请求和响应报文 2.URL结构 3.常见的方法 1.GET方法 2.POST方法 3.其他方法 三.请求报头(header) 1.Host 2.Content-Length 3.Co…

Objective-C 混用UITabBar与UINavigation

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 混用UITabBar与UINavigation做app&#xff0c;tab和nav&#xff0c;有时候显示有时候…

有关浪涌保护器参数科普

浪涌保护器&#xff08;SPD&#xff09;或简称电涌保护器是一种用于确保防止瞬态浪涌的设备。它用于保护家庭和商业应用免受电压瞬变的影响。它与必须保护的负载并联连接。 什么是瞬态浪涌&#xff1f; 瞬态浪涌是持续几微秒的功率&#xff08;电压和电流&#xff09;的突然增…

CleanMyMac X4.13.6电脑清理垃圾最干净的软件

CleanMyMac是一款Mac清理工具&#xff0c;MacOSX系统下知名系统清理软件&#xff0c;它可以流畅地与系统性能相结合&#xff0c;只需简单的步骤就可以节省硬盘空间&#xff0c;提高电脑的运行速度&#xff0c;时刻保持电脑的清洁和健康&#xff0c;监视和优化Mac的性能。 现在…

高可用数据库集群mariadb(mysql)

一、概述 是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件 二、端口号 22 三、高可用MHA简述 目前在mysql高可用方面是一个成熟的方案&#xff0c;是一套优秀的高可用环境下故障切…

在用户界面线程上等待的危险性

我们做这么一个假设哈。 如果有一个线程&#xff0c;它拥有一个窗口&#xff0c;则在这个线程的整个运行过程中&#xff0c;我们都不应该调用 Sleep 函数。为什么&#xff1f; 因为 Sleep 调用会导致线程在睡眠等待期停止处理窗口消息。即使对于持续时间较短的睡眠也是如此&a…

【正点原子STM32连载】 第三十三章 DAC实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第三…

亚马逊云服务器EC2开通Windows系统实例和远程RDP连接远程桌面

在这篇文章中&#xff0c;我们准备详细的亲测记录开通亚马逊云服务器EC2开通Windows系统。这里需要提醒的是&#xff0c;如果我们是初次免费体验亚马逊云服务器账户的话&#xff0c;是有支持单个云服务器750小时免费&#xff0c;如果我们超过部分是需要支付的&#xff0c;所以如…

探究贴纸滤镜和美颜SDK的技术实现原理

在移动应用高需求的背景下&#xff0c;贴纸滤镜和美颜SDK成为了移动应用中不可或缺的功能之一。那么&#xff0c;这些功能是如何实现的呢&#xff1f;本文将探究贴纸滤镜和美颜SDK的技术实现原理。 一、贴纸滤镜的技术实现原理 贴纸滤镜是一种可以在图片或视频上添加贴纸、滤镜…

1、DuiLib的编译和运行

文章目录 1、原生DuiLib的编译和运行1.1、下载并解压成这个样子1.2、打开.sln解决方案文件1.3、编译成功 2、网易DuiLib编译和运行2.1、下载并解压成这个样子2.2、打开.sln解决方案文件2.3、编译成功 3、腾讯DuiLib编译和运行vs 20173.1、下载并解压成这个样子3.2、打开.sln解决…

个人IP打造全过程:如何打造出属于自己的个人IP?

随着互联网的快速发展&#xff0c;个人IP已经逐渐成为一个热门话题。拥有自己的个人IP可以为你带来更多的机会和收益&#xff0c;让你在竞争激烈的市场中脱颖而出。但是&#xff0c;要想打造自己的个人IP并不是一件容易的事情。本文将为你介绍如何打造属于自己的个人IP。#IP# 一…

Burp Suite 功能详解(渗透测试工具)

一、抓包。 找到 代理--拦截--打开自带浏览器&#xff08;这里也可以自己找扩展设置代理&#xff0c;但还要添加安全证书等等&#xff0c;我觉得太麻烦了&#xff0c;还不如直接使用Burp Suite自带的浏览器抓包&#xff09;。 这是Burp Suite自带网页的页面。 点击开启拦截。 …

VMware Cloud Director Availability 4.6 | 灾难恢复和迁移 | DRaaS

VMware Cloud Director Availability 4.6 | 灾难恢复和迁移 | DRaaS 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-cloud-director-availability-4/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org VMware Cloud …

二维码在隐患排查中的应用:扫码上报,实时通知

正值安全生产月&#xff0c;对企业而言隐患排查是安全管理的重要环节&#xff0c;众多企业设立了安全部门&#xff0c;部门内的相关人员会定期对生产设备、作业场所、作业人员等进行检查&#xff0c;以确保安全隐患的消除&#xff0c;从而预防事故的发生。 传统的隐患排查主要…