Spring 的依赖注入的最常见方式

news2024/10/17 13:30:33

在这里插入图片描述

在 Spring 中,依赖注入的方式有多种选择。下面我们来逐一分析它们的特点、适用场景和注意事项:


1. 构造函数注入

构造函数注入要求在对象创建时提供所有依赖。这种方式确保依赖在对象创建后不可变,特别适合必须强制存在的依赖。所有依赖在对象实例化时即被注入,保证了依赖的一致性。

代码示例:
public class Car {
    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }
}
优点:
  • 确保依赖不可变,提升代码稳定性。
  • 更符合单一职责原则,有利于单元测试,因为构造函数明确列出了依赖项。
缺点:
  • 当依赖数量过多时,构造函数会显得过于复杂。

2. Setter 注入

Setter 注入允许在对象实例化后进行依赖的设置。相比构造函数注入,它更灵活,允许可选依赖。

代码示例:
public class Car {
    private Engine engine;

    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}
优点:
  • 更加灵活,允许在对象创建之后再注入依赖。
  • 可以处理部分依赖可能为空的情况,适合有默认依赖的场景。
缺点:
  • 可能导致对象在使用前未完成依赖的设置,增加了潜在风险。

3. 字段注入

字段注入是通过 @Autowired 直接在属性上进行注入,Spring 会自动完成依赖的注入。这种方式简化了代码,但增加了依赖管理的复杂性。

代码示例:
public class Car {
    @Autowired
    private Engine engine;
}
优点:
  • 代码简洁,不需要编写构造函数或 setter 方法。
  • 非常适合简单项目或快速开发场景。
缺点:
  • 依赖隐式注入,不易发现未初始化的属性。
  • 对单元测试不友好,需要使用反射进行依赖注入,增加测试复杂度。

4. 接口注入

接口注入通过定义特定接口,使实现类实现依赖的注入。这种方式在 Spring 项目中较少使用,但在一些严格控制的依赖关系中非常有效。

代码示例:
public interface EngineAware {
    void setEngine(Engine engine);
}

public class Car implements EngineAware {
    private Engine engine;

    @Override
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}
优点:
  • 清晰的依赖关系,强制依赖约束。
  • 更加灵活,能够在运行时动态注入依赖。
缺点:
  • 增加了接口的复杂性,通常不常用。

5. 工厂方法注入

通过 Spring 的 @Bean 注解,可以在工厂方法中生成 Bean,并进行复杂的依赖注入处理,适用于需要自定义创建逻辑的场景。

代码示例:
@Bean
public Car car() {
    return new Car(engine());
}

@Bean
public Engine engine() {
    return new Engine();
}
优点:
  • 更灵活,允许复杂依赖的创建和配置。
  • 适合处理多步骤初始化的复杂依赖。
缺点:
  • 代码较为复杂,适合高级场景,不适合简单项目。

6. @Primary@Qualifier 注解

当有多个相同类型的 Bean 时,Spring 提供了 @Primary@Qualifier 注解来决定注入哪个 Bean。@Primary 标记默认注入的 Bean,@Qualifier 用来指定具体的 Bean。

代码示例:
@Component
@Qualifier("dieselEngine")
public class DieselEngine implements Engine {}

@Component
@Primary
public class ElectricEngine implements Engine {}

@Autowired
@Qualifier("dieselEngine")
private Engine engine;
优点:
  • 能精确选择 Bean,特别是在有多个相同类型的 Bean 时。
  • 提供了更加明确的控制,避免错误的 Bean 注入。
缺点:
  • 增加了配置的复杂性,适合有多个候选 Bean 的项目。

7. 环境配置条件注入

通过 @Conditional 注解,Spring 可以根据不同的条件注入依赖。例如,根据不同的环境配置文件(如 application-dev.ymlapplication-prod.yml),来决定注入哪个 Bean。

代码示例:
@ConditionalOnProperty(name = "app.env", havingValue = "dev")
@Bean
public DataSource devDataSource() {
    return new HikariDataSource();
}

@ConditionalOnProperty(name = "app.env", havingValue = "prod")
@Bean
public DataSource prodDataSource() {
    return new DruidDataSource();
}
优点:
  • 允许根据环境动态注入 Bean,适合大型应用的多环境部署。
  • 减少了不必要的 Bean 加载,提升了性能。
缺点:
  • 需要依赖配置文件,增加了应用的复杂度。

依赖注入方式的对比

特性构造函数注入Setter 注入字段注入接口注入工厂方法注入@Primary@Qualifier环境配置注入
依赖注入时机对象创建时对象创建后框架自动完成接口回调实现工厂方法调用明确指定注入 Bean动态条件
代码简洁性较为复杂中等最简洁较复杂较复杂中等中等
灵活性较为固定灵活灵活灵活非常灵活灵活高度灵活
可维护性中等较低中等
测试友好性中等中等

结论

Spring 提供了多种依赖注入方式,每种方式都有其适用场景。构造函数注入最为稳健,但当需要灵活性时,Setter 注入和字段注入更为适合。工厂方法和条件注入适合更复杂的场景,而 @Qualifier@Primary 则用于处理多实现 Bean。根据项目需求选择合适的注入方式,才能在保持代码清晰的同时,提升可维护性和可扩展性。

在这里插入图片描述

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

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

相关文章

Windows的Conda环境下使用PlotNeuralNet来绘制神经网络

项目场景: Windows环境下,使用了anaconda的Python环境管理器,使用PlotNeuralNet来绘制神经网络图 问题描述 在运行以下shell命令的时候 cd pyexamples/ bash ../tikzmake.sh test_simple出现了访问被拒绝的错误,如下所示&#x…

【数据结构】:破译排序算法--数字世界的秩序密码(一)

文章目录 一.排序算法概述1.定义和目的2.排序算法的分类2.1比较排序2.2非比较排序 二.插入排序算法1.InsertSort直接插入排序1.1.插入排序原理1.2.插入排序过程1.3.代码实现1.4.复杂度和稳定性 2.ShellSort希尔排序2.1.希尔排序原理2.2.希尔排序过程2.3.代码实现2.4.复杂度和稳…

LeetCode 132. 分割回文串 II(经典必会)

LeetCode 132. 分割回文串 II 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串。 返回符合要求的 最少分割次数 。 示例 1: 输入:s “aab” 输出:1 解释:只需一次分割就可将 s 分割成 [“…

EditPlus安装使用

1.进入EditPlus官网(https://www.editplus.com/)点击第二行蓝字 2.点击More options第一行蓝字 3.点击exe文件进入安装,点击Accept 4.选择下载路径 4.点击editplus.exe 5.在许可证协议中点击yes 6.输入username和regcode即可使用(也可以试用30天)

Leetcode 岛屿数量

首先检查网格是否为空,如果为空,直接返回 0。遍历网格中的每一个元素,当遇到陆地(1)时,计数器加 1,并且通过 DFS 将与该陆地相连的所有部分标记为已访问(即设为 0)。DFS …

第 22 章 - 你不能错过的Elasticsearch核心知识点-BM25相关性评分算法(进阶)

文章目录 前言分片对 Elasticsearch 相关性评分的影响BM25 算法和它的变量效果应用将 b b b 值设置为 0将 k 1 k1 k1 设置为0 总结 前言 上一章介绍了 Elasticsearch 的读写优化技巧。本章将深入探讨与 Elasticsearch 相关的 BM25 相关性评分公式。 我们将全面解析 BM25 如…

【Java】C++转Java基础知识

1. Java基础知识 1.1 JDK和JVM 在Java中,JDK称为Java开发工具包(Java Development Kit),包含了Java开发需要使用的工具包,前面的版本中JRE和JDK是分开的两个文件夹,从Java9开始,JDK中还包含了JRE(Java Runtime Envir…

STM32外设详解——ADC

来源:铁头山羊 基本概念 ①ADC是模数转换器的统称,stm32f103c8t6内部集成了2个12位主次逼近型ADC,外设名称为ADC1、ADC2。 ② 采样深度为12位意味着ADC可以将0~3.3V的模拟电压等比转换为0~4095的数字值(分割为2的12次方份&…

猫头虎分享:Python库 Selenium 的简介、安装、用法详解入门教程

🐯 猫头虎分享:Python库 Selenium 的简介、安装、用法详解入门教程 🚀 今天,猫头虎带大家深入了解 Selenium,这是一个非常流行的自动化测试工具,用于浏览器自动化。无论你是进行网页数据抓取,还…

Starrocks表的数据库字段类型及与MySQL 的差异

最近有用到Starrocks,实际使用中基本可以当作mysql来使用,但是数据库字段还是有所不同的。 与MySQL相同或相似的基础类型 数值类型 TINYINT、SMALLINT、INT/INTEGER、BIGINT:在Starrocks和MySQL中的定义和用途基本相似。都是用于存储整数&…

YOLO11改进|注意力机制篇|引入Mamba注意力机制MLLAttention

目录 一、【MLLAttention】注意力机制1.1【MLLAttention】注意力介绍1.2【MLLAttention】核心代码 二、添加【MLLAttention】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP42.5STEP5 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【MLLAttention】注意力机制 1.1【MLLAtte…

[Linux#66][TCP->IP] 面向字节流 | TCP异常 | filesocket | 网络层IP

目录 1. 面向字节流 思考:对于UDP协议来说,是否也存在“粘包问题”呢? 2.TCP 异常情况 3.知识 1.UDP实现可靠传输(经典面试题) 2. 网络抓包 | 爬虫 3.打通文件和 socket 的关系 4.网络层:IP 前置知识 1. 面向字节流 udp…

Java+vue部署版本反编译

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&am…

C++STL(2)

queue(队列) queue是一种先进先出的数据结构。 queue提供了一组函数来操作和访问元素,但它的功能相对较简单。 push(x):在队尾插入元素 x pop():弹出队首元素 front():返回队首元素 back():返回队尾元素 empty():检查队列是否为空 size0:返回队列中元素的个数 pri…

Android ViewModel

一问:ViewModel如何保证应用配置变化后能够自动继续存在,其原理是什么,ViewModel的生命周期和谁绑定的? ViewModel 的确能够在应用配置发生变化(例如屏幕旋转)后继续存在,这得益于 Android 系统的 ViewMod…

模拟电子电路基础(常见半导体+multisim学习1)

目录 1.半导体的基础 1.1.半导体基础知识 1.1.1本征半导体 1.1.2杂质半导体 1.1.3PN结 1.2半导体二极管 1.2.1半导体二极管的几种常见结构 1.2.2二极管的伏安特性曲线 1.2.3二极管的主要参数 1.2.4二级管的等效电路 1.2.5稳压二极管 1.2.其他类型二极管 2.multisim的…

双目视觉搭配YOLO实现3D测量

一、简介 双目(Stereo Vision)技术是一种利用两个相机来模拟人眼视觉的技术。通过对两个相机获取到的图像进行分析和匹配,可以计算出物体的深度信息。双目技术可以实现物体的三维重建、距离测量、运动分析等应用。 双目技术的原理是通过两…

Docker-nginx数据卷挂载

数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。 以Nginx为例,我们知道Nginx中有两个关键的目录: html:放置一些静态资源conf:放置配置文件 如果我们要让Nginx代理我们…

java项目之厨艺交流平台设计与实现(源码+文档)

项目简介 厨艺交流平台设计与实现实现了以下功能: 厨艺交流平台设计与实现的主要使用者管理员管理用户信息,可以添加,修改,删除用户信息信息。 💕💕作者:落落 💕💕个人…

分享一个从图片中提取色卡的实现

概述 最近在做“在线地图样式配置”的功能的时候,发现百度地图有个功能时上传一张图片,从图片中提取颜色并进行配图。本文就简单实现一下如何从图片中提取色卡。 效果 实现 实现思路 通过canvasdrawImage绘制图片,并通过getImageData获取…