【Spring】Spring中8种常见依赖注入使用示例

在 Spring 中,IoC 注入可以通过多种方式实现,涵盖不同场景的依赖管理。以下是 8 种常见场景的详细示例及说明,结合 XML、注解和 Java 配置类三种方式。


1. 构造器注入(推荐方式)

通过构造器传递依赖,确保对象不可变且依赖完整。

注解方式:
@Service
public class OrderService {private final PaymentService paymentService;@Autowired // Spring 4.3+ 可省略(单构造器时)public OrderService(PaymentService paymentService) {this.paymentService = paymentService;}
}@Component
public class PaymentService {public void process() {System.out.println("Processing payment...");}
}
XML 方式:
<bean id="paymentService" class="com.example.PaymentService"/><bean id="orderService" class="com.example.OrderService"><constructor-arg ref="paymentService"/>
</bean>
Java 配置类:
@Configuration
public class AppConfig {@Beanpublic PaymentService paymentService() {return new PaymentService();}@Beanpublic OrderService orderService() {return new OrderService(paymentService());}
}

2. Setter 注入

通过 Setter 方法注入依赖,适合可选依赖或需要动态变更的场景。

注解方式:
@Service
public class ProductService {private InventoryService inventoryService;@Autowiredpublic void setInventoryService(InventoryService inventoryService) {this.inventoryService = inventoryService;}
}@Component
public class InventoryService {public void checkStock() {System.out.println("Checking stock...");}
}
XML 方式:
<bean id="inventoryService" class="com.example.InventoryService"/><bean id="productService" class="com.example.ProductService"><property name="inventoryService" ref="inventoryService"/>
</bean>

3. 字段注入(不推荐,但常见)

直接通过字段注入依赖,简洁但隐藏依赖关系。

@Service
public class CartService {@Autowiredprivate DiscountService discountService;
}@Component
public class DiscountService {public void applyDiscount() {System.out.println("Applying discount...");}
}

4. 集合注入(多个同类型 Bean)

注入多个相同接口/父类的实现类。

示例代码:
public interface NotificationSender {void send(String message);
}@Component
public class EmailSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("Email: " + message);}
}@Component
public class SmsSender implements NotificationSender {@Overridepublic void send(String message) {System.out.println("SMS: " + message);}
}
注入方式:
@Service
public class NotificationService {private final List<NotificationSender> senders;@Autowiredpublic NotificationService(List<NotificationSender> senders) {this.senders = senders;}public void broadcast(String message) {senders.forEach(sender -> sender.send(message));}
}

5. 条件注入(@Qualifier 或 @Primary)

解决多个同类型 Bean 的歧义性问题。

使用 @Qualifier
public interface DataSource {void connect();
}@Component("mysqlDataSource")
public class MySqlDataSource implements DataSource {@Overridepublic void connect() {System.out.println("MySQL connected");}
}@Component("oracleDataSource")
public class OracleDataSource implements DataSource {@Overridepublic void connect() {System.out.println("Oracle connected");}
}@Service
public class ReportService {private final DataSource dataSource;@Autowiredpublic ReportService(@Qualifier("mysqlDataSource") DataSource dataSource) {this.dataSource = dataSource;}
}
使用 @Primary
@Configuration
public class AppConfig {@Bean@Primary // 默认优先选择public DataSource mysqlDataSource() {return new MySqlDataSource();}@Beanpublic DataSource oracleDataSource() {return new OracleDataSource();}
}

6. 外部化配置注入(@Value)

注入配置文件(如 application.properties)中的值。

配置文件:
app.name=MySpringApp
app.max.connections=10
注入方式:
@Component
public class AppConfigBean {@Value("${app.name}")private String appName;@Value("${app.max.connections}")private int maxConnections;// Getter/Setter
}

7. 循环依赖处理

构造器注入无法解决循环依赖,需改用 Setter 注入。

示例代码:
@Service
public class ServiceA {private ServiceB serviceB;@Autowiredpublic void setServiceB(ServiceB serviceB) {this.serviceB = serviceB;}
}@Service
public class ServiceB {private ServiceA serviceA;@Autowiredpublic void setServiceA(ServiceA serviceA) {this.serviceA = serviceA;}
}

8. 条件化 Bean 注入(@Profile 或 @Conditional)

根据环境或条件动态选择 Bean。

使用 @Profile
@Configuration
public class DataSourceConfig {@Bean@Profile("dev")public DataSource devDataSource() {return new H2DataSource();}@Bean@Profile("prod")public DataSource prodDataSource() {return new MySqlDataSource();}
}
使用 @Conditional
public class MongoDBCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return "true".equals(context.getEnvironment().getProperty("enable.mongo"));}
}@Configuration
public class DatabaseConfig {@Bean@Conditional(MongoDBCondition.class)public DataSource mongoDataSource() {return new MongoDataSource();}
}

总结

  • 构造器注入:推荐用于强制依赖,确保对象不可变。
  • Setter/字段注入:适合可选依赖或需要灵活性的场景。
  • 集合注入:处理多实现类的统一管理。
  • 条件注入:通过 @Qualifier@Primary@Profile 解决歧义。
  • 循环依赖:优先通过设计避免,或改用 Setter 注入。
  • 外部化配置:结合 @Value 动态注入属性值。
  • 条件化 Bean:根据环境或业务规则动态装配。

具体选择取决于项目需求,Spring Boot 进一步简化了配置(如自动配置、@ConditionalOnProperty)。

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

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

相关文章

蓝桥杯 摆动序列

摆动序列 原题目链接 题目描述 如果一个序列的奇数项都比前一项大&#xff0c;偶数项都比前一项小&#xff0c;则称为一个摆动序列。 即对于任意整数 i&#xff08;i ≥ 1&#xff09;满足&#xff1a; a₂ᵢ < a₂ᵢ₋₁&#xff0c;a₂ᵢ₊₁ > a₂ᵢ 小明想知道&…

REINFORCE蒙特卡罗策略梯度算法详解:python从零实现

&#x1f9e0; 向所有学习者致敬&#xff01; “学习不是装满一桶水&#xff0c;而是点燃一把火。” —— 叶芝 我的博客主页&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 欢迎点击加入AI人工智能社区&#xff01; &#x1f680; 让我们一起努力&#xff0c;共创…

深入了解Linux系统—— 操作系统

一、冯诺依曼体系结构 现在我们常见的计算机&#xff08;笔记本电脑等&#xff09;和不常见的计算机&#xff08;服务器&#xff09;它们都满足冯诺依曼体系。 我们可以把计算机理解成一个个硬件组成的 输入设备&#xff1a;键盘、鼠标、摄像头、网卡、磁盘等输出设备&#xf…

RPG7.准备GAS的工作

1.启动项目&#xff0c;为项目添加gameplayability插件 2.添加abilitysystemcomponent的c类 3.添加attributeset的c类 4.往build.cs内添加模块 5.进入CharacterBase内&#xff0c;添加gameplayasystem和attributbeset&#xff0c;覆写PossessedBy()和GetAbilitysystemcomponent…

使用gitea发布软件包

1、新建hello工程 &#xff08;1&#xff09;HelloApplication.java package cn.ac.trimps.sv;import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplicati…

从请求到响应:初探spring web

引入&#xff1a; 首先小编想分享下一些开发小知识 2000年——手写servlet/JSP时代 在这个阶段中&#xff0c;那时候写后端代码&#xff0c;可谓是个麻烦事。 毕竟什么都要自己干 发来的请求都要写extends HttpServlet的类&#xff0c;手动在web.xml配置 <servlet>…

Redis从入门到实战实战篇2

面试重点&#xff1a;本篇包含悲观锁&#xff0c;乐观锁&#xff0c;多线程以及分布式锁的知识 目录 3.优惠卷秒杀 3.1 -全局唯一ID 3.2 -Redis实现全局唯一Id 3.3 添加优惠卷 3.4 实现秒杀下单 3.5 库存超卖问题分析 3.6 乐观锁解决超卖问题 3.7 优惠券秒杀-一人一单 …

LabVIEW实验室项目中使用类模块与仿真

在 LabVIEW 程序开发过程中&#xff0c;借鉴面向对象的类思想进行模块化架构设计&#xff0c;并结合仿真功能&#xff0c;能够高效应对不同场景的开发需求。 ​ 以实验室场景为例&#xff0c;LabVIEW 开发常面临设备种类繁多、调试周期漫长&#xff0c;且硬件难以一次性到位的情…

ES6入门---第二单元 模块三:对象新增、

一&#xff1a;对象简洁语法&#xff1a; 1、变量简洁 <script>let name Strive;let age 18;let json {name, //name:name,age //age:age};console.log(json);</script> 2、函数简洁 let json {name, //name:name,age, //age:age/* showA:functi…

Python创意:AI图像生成——用代码绘制未来艺术

当代码邂逅艺术:AI图像生成的革命 在数字艺术领域,一场由Python和AI技术引领的革命正在悄然发生。无需专业绘画技巧,仅凭几行代码,普通人也能创造出令人惊叹的艺术作品。AI图像生成技术打破了艺术创作的门槛,让想象力成为唯一的限制。 核心技术方案 1. 技术架构 我们采…

一、Shell 脚本基础

一、Shell 简介 1.Shell 的定义与作用 Shell&#xff0c;通常被称为命令行解释器 (Command Line Interpreter)&#xff0c;是用户 &#x1f464; 与 Linux/Unix 操作系统内核进行交互 ↔️ 的“桥梁” &#x1f309;。它扮演着翻译官 &#x1f5e3;️ 的角色&#xff1a; 接…

青少年编程与数学 02-018 C++数据结构与算法 21课题、机器学习与人工智能算法

青少年编程与数学 02-018 C数据结构与算法 21课题、机器学习与人工智能算法 一、线性回归算法二、逻辑回归算法三、K近邻算法&#xff08;K-Nearest Neighbors, KNN&#xff09;四、决策树算法五、支持向量机&#xff08;SVM&#xff09;六、神经网络算法七、聚类算法八、降维算…

【数据结构】——单链表练习(1)

一、移除链表元素 题目链接&#xff1a; 移除链表元素 那么根据题目的要求我们大致明白这道题要做什么&#xff0c;就是将一个链表中&#xff0c;和指定的值相等的元素的节点删除&#xff0c;然后返回删除后的新的链表&#xff0c;然后题目给我们传入的参数是链表的头节点和指…

AI大模型基础设施:主流的几款开源AI大语言模型的本地部署成本

以下是对目前主流开源AI大语言模型&#xff08;如DeepSeek R1、LLaMA系列、Qwen等&#xff09;本地部署成本的详细分析&#xff0c;涵盖计算机硬件、显卡等成本&#xff0c;价格以美元计算。成本估算基于模型参数规模、硬件需求&#xff08;GPU、CPU、RAM、存储等&#xff09;以…

AI生成视频检测方法及其相关研究

目录标题 【1】AI-Generated Video Detection via Spatio-Temporal Anomaly Learning【2】DeCoF: Generated Video Detection via Frame Consistency【2.1】Spatiotemporal Convolutional Neural Networks (STCNN) rely on spatial artifacts【2.2】Capturing Universal Spatia…

仿腾讯会议——服务器注释

目录 1、修改协议 2、修改登录请求结构体 3、修改登录回复结构体 4、修改注册请求结构体 5、修改发送登录请求函数 6、实现发送注册请求函数 7、修改mysql存储数据格式 8、自己完成部分 1、修改协议 2、修改登录请求结构体 3、修改登录回复结构体 4、修改注册请求结构体…

list的迭代器详讲

1.list的迭代器就是封装了节点指针的类 2.迭代器失效 迭代器失效即迭代器封装的节点指针无效 。因为 list 的底层结构为带头结点的双向循环链表 &#xff0c;因此 在 list 中进行插入时是不会导致 list 的迭代 器失效的&#xff0c;只有在删除时才会失效&#xff0c;并且失效的…

deepSeek论文写作提示词指令大全(覆盖选题、写作、润色到投稿全流程)

一、选题与框架设计 1、跨学科选题突破 指令:"结合[领域A]与[领域B]的前沿理论,生成5个交叉创新性论文选题,要求每个选题包含可行性评估。"(支持跨学科研究创新) 示例:"在人工智能与教育心理学领域生成选题,分析理论适用性与资源获取难度。" 2、…

win11安装WSL(创建用户、更改或重置密码)

文章目录 win11安装WSL设置 Linux 用户名和密码更改或重置密码更新和升级软件包WSL 命令互操作性WSL 的基本命令安装列出可用的 Linux 发行版列出已安装的 Linux 发行版将 WSL 版本设置为 1 或 2设置默认 WSL 版本设置默认 Linux 发行版将目录更改为主页通过 PowerShell 或 CMD…

Vue.js 与 Ajax (vue-resource) 的深入解析

Vue.js 与 Ajax (vue-resource) 的深入解析 引言 在Web开发中,前后端的交互是不可或缺的。Ajax(异步JavaScript和XML)技术允许我们在不重新加载整个页面的情况下,与服务器交换数据和更新部分网页内容。Vue.js 作为一种流行的前端框架,提供了多种方式来处理Ajax请求。其中…