Spring IoC DI 之 属性注入

 一、DI (依赖注入)

依赖注入(DI)是一种实现控制反转(IoC)的技术,可以在运行时动态地向应用程序提供其所需的依赖。在 Spring 框架中,DI 是一种常用的实践,有助于提高代码的模块化和灵活性。下面是依赖注入的一些关键点和优势:

依赖注入的工作原理
  1. 容器管理

    • 在 Spring 中,容器负责创建和管理对象(即 Beans)。开发者只需要通过配置(可以是 XML 文件、注解或 Java 配置类)指定依赖关系。
  2. 注入方式

    • 构造器注入:通过构造函数传递依赖。
    • 设置器注入:通过 JavaBean 属性的 setter 方法传递依赖。
    • 字段注入:直接在字段上注入依赖,通常使用 @Autowired 注解。
  3. 运行时绑定

    • 依赖注入是在运行时处理的,这意味着应用程序的组件可以在不修改代码的情况下,通过更改配置来使用不同的依赖实现。

二、使用 字段注入自动注入 Bean

在 Spring 的组件(如由 @Component, @Service, @Controller 等注解标记的类)中,你可以使用 @Autowired 注解自动注入 Bean。这是推荐的方法,因为它减少了对 Spring API 的直接依赖,并且使得代码更加简洁。

@Component
public class UserService {@Autowiredprivate User user;public void displayUser() {System.out.println("User Name: " + user.getName());}
}

Spring 应用中使用 @Autowired 注解自动注入 Bean 且存在多个相同类型的 Bean 时,会出现冲突,因为 Spring 不知道应该注入哪一个。为了解决这个问题,Spring 提供了几种方法来指定要注入的具体 Bean,确保准确性和灵活性。

1)指定Bean 注入
a) 使用 @Qualifier 注解

@Qualifier 注解用来进一步细化 @Autowired 的注入选择。通过为每个 Bean 定义一个名称,然后在注入时指定这个名称,可以控制哪一个 Bean 被注入。

@Component
public class VehicleService {@Autowired@Qualifier("car")private Vehicle vehicle;public void service() {vehicle.performService();}
}@Component("car")
public class Car implements Vehicle {@Overridepublic void performService() {System.out.println("Servicing a car");}
}@Component("bike")
public class Bike implements Vehicle {@Overridepublic void performService() {System.out.println("Servicing a bike");}
}

在这个例子中,我们有两个 Vehicle 类型的 Bean,分别是 CarBike。使用 @Qualifier("car") 告诉 Spring 在注入 Vehicle 类型的依赖时使用名为 "car" 的 Bean 

b)  使用 @Primary 注解

当你想要在多个相同类型的 Bean 中指定一个“默认”Bean 时,可以使用 @Primary 注解。当存在多个 Bean 且其中一个被标记为 @Primary,Spring 会优先注入这个 Bean。

@Component
@Primary
public class Car implements Vehicle {@Overridepublic void performService() {System.out.println("Servicing a car");}
}@Component
public class Bike implements Vehicle {@Overridepublic void performService() {System.out.println("Servicing a bike");}
}@Component
public class VehicleService {@Autowiredprivate Vehicle vehicle;  // 默认注入 @Primary 标记的 Beanpublic void service() {vehicle.performService();}
}

在这个例子中,Car 类被标记为 @Primary,因此它会被默认注入到 VehicleService 中,除非使用 @Qualifier 明确指定其他 Bean。

c)  使用特定方法命名或 @Bean 注解中的名称

在 Java 配置类中,你可以通过方法名称或在 @Bean 注解中指定名称来控制 Bean 的标识符。然后,可以结合使用 @Autowired@Qualifier

@Configuration
public class AppConfig {@Bean(name = "car")public Vehicle car() {return new Car();}@Bean(name = "bike")public Vehicle bike() {return new Bike();}
}

然后,使用 @Qualifier 来指定注入哪一个。

通过这些方法,你可以在 Spring 中精确控制哪个 Bean 被注入到有多个相同类型的 Bean 的情况下,从而保证应用的正确性和灵活性。

2)使用 @Resource 或 @Inject 注解

@Resource@Inject 是 JSR-250 和 JSR-330 的标准 Java 注解,分别来自 Java EE 和依赖注入规范。它们与 @Autowired 类似,但略有不同的注入语义和配置方式。

示例代码(使用 @Resource):

@Component
public class UserService {@Resource(name="user")private User user;public void displayUser() {System.out.println("User Name: " + user.getName());}
}

三、  构造方法注入

这种方式是最推荐的,因为它确保了所有的依赖在对象被创建之前就已经准备好了。

@Component
public class UserService {private final UserRepository userRepository;@Autowiredpublic UserService(UserRepository userRepository) {this.userRepository = userRepository;}public void performAction() {System.out.println("Action performed with user repository.");}
}

四、Setter 方法注入

这种方法适用于可选依赖,或者在对象创建之后还可以更改依赖的情况

@Component
public class NotificationService {private EmailService emailService;@Autowiredpublic void setEmailService(EmailService emailService) {this.emailService = emailService;}public void sendNotification(String message, String recipient) {emailService.sendEmail(message, recipient);}
}@Component
public class EmailService {public void sendEmail(String message, String recipient) {System.out.println("Email sent to " + recipient + " with message: " + message);}
}

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

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

相关文章

Nginx反向代理配置支持websocket

一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket,使用了HTTP/1.1中可用的协议切换机制(RFC 2616: Hypertext Transfer Protocol – HTTP/1.1)。 然而,这里有一个微妙之处:由于“升级”…

论文阅读:A Generalization of Transformer Networks to Graphs

论文阅读:A Generalization of Transformer Networks to Graphs 论文地址1 摘要2 贡献Graph TransformerOn Graph Sparsity(图稀疏)On Positional Encodings(位置编码)3 Graph Transformer Architecture(架…

C++:日期类的实现

目录 一、前言 二、头文件 三、各个函数的实现 打印、检查日期及获取日期 、、-、-、 、<、<、>、>、 &#xff01; 日期-日期 >>、<< 一、前言 前面几篇讲了关于类和对象的一些知识&#xff0c;本篇就来实现一下前面用到的日期类。 二、头文…

市面第一款 C++ 版本的U盘装机软件(即将上线)

市面大部分U盘装机软件&#xff0c;都是采用Au3脚本开发&#xff0c;而且有各种捆绑&#xff0c;闲来无聊&#xff0c;采用Qt C制作一款CU盘装机软件&#xff0c;从此告别Au3脚本&#xff0c;各种炫酷界面随便换&#xff0c;敬请期待 另外两个界面暂时不公布&#xff0c;防止Au…

uni-app页面调用接口和路由(四)

文章目录 一、路由二、页面调用接口二、路由跳转1.uni.navigateTo(OBJECT)2.uni.redirectTo(OBJECT)3.uni.reLaunch(OBJECT)4.uni.switchTab(OBJECT)5.uni.navigateBack(OBJECT) 总结 一、路由 路由配置 uni-app页面路由为框架统一管理&#xff0c;开发者需要在pages.json里配…

Linux —— Socket编程(一)

一、本篇重点 1. 认识IP地址、端口号、网络字节序等网络编程中的基本概念 2. 学习Socket api的基本用法 3. 能够实现一个简单的udp客户端/服务器 二、基本概念 1. 理解源IP地址和目的IP地址 简单的理解&#xff0c;IP地址是用于标识一台机器的&#xff0c;我们通过IP地址去…

Springboot常见问题(bean找不到)

如图错误显示userMapper bean没有找到。 解决方案&#xff1a; mapper包位置有问题&#xff1a;因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题&#xff1a; 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…

大数据Hologres(一):Hologres 简单介绍

文章目录 Hologres 简单介绍 一、什么是实时数仓 Hologres 二、产品优势 1、专注实时场景 2、亚秒级交互式分析 3、统一数据服务出口 4、开放生态 5、MaxCompute查询加速 6、计算存储分离架构 三、应用场景 搭建实时数仓 四、产品架构 1、Shared Disk/Storage &am…

ER 图 Entity-Relationship (ER) diagram 101 电子商城 数据库设计

起因&#xff0c; 目的: 客户需求, 就是要设计一个数据库。 过程&#xff0c; 关于工具: UI 设计&#xff0c;我最喜欢的工具其实是 Canva, 但是 Canva 没有合适的模板。我用的是 draw.io, 使用感受是&#xff0c;很垃圾。 各种快捷键不适应&#xff0c;箭头就是点不住&…

OpenCV4.8 开发实战系列专栏之 01- 环境搭建与图像读写

大家好&#xff0c;欢迎大家学习OpenCV4.8 开发实战专栏&#xff0c;长期更新&#xff0c;不断分享源码。 专栏代码全部基于C 与Python双语演示&#xff0c;专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点&#xff1a; 开发环境搭建、读取图像与显示图像,读取图像…

【笔记篇】一篇文章搞定Spring框架

文章目录 前言一、Spring框架的优势 二、 Spring的使用流程Spring的依赖注入bean后处理器容器后处理器FileSystemResource类Spring的AOP机制AOP基础知识AOP应用案例Spring的事务管理事务控制参数事务的隔离级别 总结 前言 学习完了Spring框架&#xff0c;总结回顾一下。 一、…

使用vite+react+ts+Ant Design开发后台管理项目(三)

前言 本文将引导开发者从零基础开始&#xff0c;运用vite、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈&#xff0c;构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导&#xff0c;文章旨在为开发者揭示如何利用这些技术…

工程师 - Windows下打开PowerShell和CMD Prompt的若干方法

打开PowerShell 在Windows中&#xff0c;你可以通过以下几种方式来打开PowerShell&#xff1a; 1. 开始菜单&#xff08;Start Menu&#xff09;&#xff1a;点击“开始”按钮&#xff0c;然后在搜索栏中输入“PowerShell”。在搜索结果中&#xff0c;选择“Windows PowerShell…

夹耳式蓝牙耳机哪个牌子最好?夹耳式耳机推荐性价比排行榜

耳夹式耳机既不堵耳孔、也不需要包覆耳廓&#xff0c;佩戴时看起来更像是一个“耳环”&#xff0c;固定方式也类似“夹耳朵”。不过&#xff0c;它并不是真的夹住了耳朵肉&#xff0c;而是半夹、半挂——依靠耳廓边缘厚、里面薄&#xff0c;且有一定的弯折面的特殊构造&#xf…

网络层协议 —— IP协议

目录 0.前言 1.IP协议的格式 2.IP地址 2.1IP地址的划分 国际间IP地址的划分 公有IP 私有IP 特殊的IP地址 国内IP地址的划分 2.2IP地址不足问题 2.3IP地址的功能 2.4如何使用IP地址 2.5IP地址的构成 3.网段划分 以前的方案 现在的方案 4.认识宏观网络 5.路由 …

边缘智能-大模型架构初探

R2Cloud接口 机器人注册 请求和应答 注册是一个简单的 HTTP 接口&#xff0c;根据机器人/用户信息注册&#xff0c;创建一个新机器人。 请求 URL URLhttp://ip/robot/regTypePOSTHTTP Version1.1Content-Typeapplication/json 请求参数 Param含义Rule是否必须缺省roboti…

[vulnhub] Hackademic.RTB1

第一次打靶机&#xff0c;思路看的红队笔记 https://www.vulnhub.com/entry/hackademic-rtb1,17/ 环境&#xff1a;kali Linux - 192.168.75.131&#xff0c;靶机 - 192.168.75.132 主机发现和端口扫描 扫描整个网络有哪台机子在线&#xff0c;不进行端口扫描 nmap -sP 192.16…

竹云赋能“中国·贵州”全省统一移动应用平台建设,打造政务服务“新引擎”

近日&#xff0c;2024中国国际大数据产业博览会在贵州贵阳圆满落幕。会上&#xff0c;由贵州省政府办公厅牵头建设的“中国贵州”全省统一移动应用平台正式发布&#xff0c;聚焦民生办事、政务公开、政民互动、扁平高效、数据赋能五大模块&#xff0c;旨在打造公平普惠的服务平…

【2020工业图像异常检测文献】PaDiM

PaDiM: a Patch Distribution Modeling Framework for Anomaly Detection and Localization 1、Background 在单类学习&#xff08;仅使用正常数据&#xff08;即“单一类”&#xff09;来训练模型&#xff09;环境中的异常检测和定位任务方法中&#xff0c;要么需要深度神经网…

ubuntu 安装minikube,并拉取k8s镜像

虚拟机是vmware17, 系统是ubuntu20.4&#xff0c; minikube是1.23.1&#xff0c; docker是24.0.7&#xff0c; 为什么要装minikube&#xff0c;通常k8s集群是要3台机子以上&#xff0c;而通过minikube&#xff0c;可以在一台机子上搭建出k8s集群&#xff0c;minikube采用的是D…