Spring Framework中的依赖注入:构造器注入 vs. Setter注入

前言

构造器注入和Setter注入是依赖注入(Dependency Injection,DI)中两种常见的方式,用于向一个对象注入其所依赖的其他对象或数值。这两种注入方式有各自的特点和用途。

构造器注入(Constructor Injection):

在构造器注入中,依赖关系通过类的构造函数传递。这意味着在创建对象时,依赖的对象实例会作为构造函数的参数传递进来。

示例(Java):

public class UserService {
    private UserRepository userRepository;

    // 构造器注入
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // 其他方法使用userRepository
}

优点:

  1. 对象的依赖关系在创建时就被确定,对象一旦创建就不可变,有助于保持对象的一致性和可靠性。
  2. 在构造函数中明确声明依赖,可以使类的使用更加清晰,减少了后续对依赖的猜测。

Setter注入(Setter Injection):

在Setter注入中,依赖通过类的setter方法进行注入。这意味着你可以在对象创建后随时改变依赖关系。

示例(Java):

public class UserService {
    private UserRepository userRepository;

    // Setter注入
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // 其他方法使用userRepository
}

优点:

  1. 灵活性高,可以在运行时动态更改依赖关系。
  2. 允许逐步构建对象,不需要一次性提供所有依赖。

选择构造器注入还是Setter注入取决于以下因素:

  1. 不变性需求: 如果对象的依赖关系在创建后不应该更改,构造器注入是一个好的选择。
  2. 灵活性需求: 如果对象的依赖关系可能在运行时更改,Setter注入更为合适。
  3. 清晰性: 构造器注入通常更容易理解,因为依赖关系在对象创建时就被确定。
  4. 依赖数量: 如果类有大量的依赖,构造器注入可能更清晰,而不是在构造函数中添加大量的参数。

在实践中,有时也可以使用构造器注入和Setter注入的组合,以满足不同的需求。

当前Spring Framework版本对两者的看法

Spring Framework是一个流行的Java开发框架,它提供了丰富的功能,包括依赖注入(Dependency Injection)的支持。Spring对构造器注入和Setter注入都提供了良好的支持,而且在不同版本中,它并没有显著改变对这两种注入方式的看法。当前版本Spring Framework更推荐通过构造方法注入Bean。

来自“Constructor-based or setter-based DI”

“The Spring team generally advocates constructor injection, as it lets

you implement application components as immutable objects and ensures that required dependencies are not null.

Spring团队通常提倡构造函数注入,因为它允许

将应用程序组件实现为不可变对象,并确保所需的依赖项不为空。

Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

此外,构造器注入的组件总是以完全初始化的状态返回给客户端(调用)代码。顺便说一句,大量的构造函数参数是一种不好的代码气味,这意味着类可能有太多的职责,应该重构以更好地解决适当的关注点分离问题。

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later.

Management through JMX MBeans is therefore a compelling use case for setter injection.”

Setter注入应该主要只用于可选的依赖项,这些依赖项可以在类中被分配合理的默认值。否则,必须在代码使用依赖项的任何地方执行非空检查。setter注入的一个好处是,setter方法使该类的对象可以在以后重新配置或重新注入。

因此,通过JMX MBeans进行管理是setter注入的一个引人注目的用例。”

总结

总结以上论点就是:

  • 构造器注入提倡不可变性: 通过构造器注入对象,实现了对象初始化后的不可变性,同时确保所需依赖不为空。这有助于保持对象状态的稳定性。
  • 构造器注入促使代码质量提升: 通过构造器注入,可以清晰地看到类的依赖关系,大量构造器参数说明当前类耦合过多、职责过多,从而促使编码者考虑是否需要重构,以提高代码质量和可维护性。
  • Setter注入适用于可选依赖: Setter注入主要用于可选依赖,这些依赖可以在类内部被合理默认赋值。然而,需要注意的是,Setter注入的对象需要进行非空检查,因为它们具有可变性。
  • Setter注入支持对象的动态重配置: 通过Setter注入,对象可以在运行时进行重新配置或重新注入。这使得Setter注入在JMX MBeans等需要动态管理的场景下变得特别有用。

pexels-jonathan-borba-18894303.jpg

关于我

👋🏻你好,我是Debug.c。微信公众号:种颗代码技术树 的维护者,一个跨专业自学Java,对技术保持热爱的bug猿,同样也是在某二线城市打拼四年余的Java Coder。

🏆在掘金、CSDN、公众号我将分享我最近学习的内容、踩过的坑以及自己对技术的理解。

📞如果您对我感兴趣,请联系我,

⭐️若有收获,就点个赞吧。

⛰若喜欢文中配图,请联系我,我发您原图。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工作记录-------MySql主从同步

MySql主从同步简述: MySQL主从同步,可以实现将数据从一台数据库服务器同步到多台数据库服务器。MySQL数据库自带主从同步功能,经过配置,可以实现基于库、表结构的多种方案的主从同步。 Redis是一种高性能的内存数据库&#xff1…

NSSCTF第12页(1)

[FSCTF 2023]细狗2.0 应该是和[HUBUCTF 2022 新生赛]ezsql搞混掉了 点击按钮出现了 发现输入什么回显什么 伪协议也不行 看源代码发现了这个玩意 输入了1;发现了其他回显 ls 发现了两个文件 发现被限制了 不知道是cat还是空格 绕过 直接找吧还是 得到flag [SCTF 2021]loginm…

iceoryx(冰羚)-Service Discovery

Service Discovery Summary and problem description IPC通道(例如消息队列或UNIX域套接字)上的服务发现是不可执行的,因为传输的数据较大,这可能会导致多个帧的传输。如果发现大量高频服务,例如在启动时&#xff0c…

jetson配置笔记

typora-root-url: /home/msj/ubuntu笔记本台式机环境配置说明/images Ubuntu18.04 配置 说明:我们所有文档配置都是按照ubuntu18.04,保证x86架构(笔记本台式机)和 ARM架构(jetson Nano只能安装18.04)的一致性 1. 更换各类源 我们所有源都更换清华源&a…

【教学类-07-08】20231114《破译电话号码-图形篇(图形固定列不重复)》(大4班 有名字 有班级 无学号、零=0)

效果展示 背景需求: 最近大4班做“嵌套骰子”非常频繁,为了避免“疲劳”,我找出他们班家长的手机号,批量做了“破译电话号码”,有图案版和加减法版,考虑到第一次做,还是选最简单的“点数总数&a…

C++算法:全 O(1) 的数据结构

题目 请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。 实现 AllOne 类: AllOne() 初始化数据结构的对象。 inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key…

蒙特卡洛树搜索(Monte Carlo Tree Search)揭秘

一. 什么是蒙特卡洛树搜索 蒙特卡洛树搜索(MCTS)是一种启发式搜索算法,一般用在棋牌游戏中,如围棋、西洋棋、象棋、黑白棋、德州扑克等。MCTS与人工神经网络结合,可发挥巨大的作用,典型的例子是2016年的AlphaGo,以4:1…

压测工具主要功能是什么?该怎样选择?

压测工具是一类用于模拟并评估系统在不同负载条件下的性能的软件应用程序。通过模拟大量用户同时访问系统,压测工具能够帮助开发者识别系统的瓶颈、性能瓶颈以及潜在的故障点。这种实时、模拟的方式允许开发者在正式投入使用之前发现并解决问题,提高系统…

MySQL8 绿色版安装

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: MySQL学习 ✨特色专栏: My…

数据结构线性表——队列

前言:哈喽小伙伴们,这篇文章我们继续来学习线性表的第五章——队列。 世上无难事,只怕有心人。数据结构看似有很多种类型,但是它们之间都有着千丝万缕的联系。 只要我们能够耐心学习思考,就一定能够将知识串通起来&a…

一例plugx样本的分析(AcroRd32cWP)

这是一例plugx的样本,使用了一个合法签名的程序 ,使用侧加载的方式加载一个恶意的dll,解密一个dat文件来,在内存中执行一个反射型dll来完成恶意功能。 这个病毒会使用摆渡的方式的来窃取内网的文档数据,具有严重的失泄…

c语言11周(16~20)

利用函数求和 //只填写要求的函数 double fun(int n) {double s 0;int i;for (i 1; i < n; i) {s 1.0 / (i * i);}return s; } 编写char fun(char c)函数&#xff0c;将数字参数字符c按如下规则转换。 题干编写char fun(char c)函数&#xff0c;将数字参数字符c按如…

YOLO目标检测——苹果数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;监测果园中苹果的生长情况、水果品质监控、自动化分拣数据集说明&#xff1a;苹果检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(…

《视觉SLAM十四讲》-- 后端 1(上)

文章目录 08 后端 18.1 概述8.1.1 状态估计的概率解释8.1.2 线性系统和卡尔曼滤波&#xff08;KF&#xff09;8.1.3 非线性系统和扩展卡尔曼滤波&#xff08;EKF&#xff09;8.1.4 小结 08 后端 1 前端视觉里程计可以给出一个短时间内的轨迹和地图&#xff0c;但由于不可避免的…

项目经理为什么要考PMP?PMP考试条件有哪些?

考得PMP&#xff0c;项目经理可以有以下收获&#xff1a; 1、面试条件上&#xff1a;有PMP证书优先&#xff1b; 2、覆盖行业和职位范围广&#xff0c;医疗&#xff0c;互联网&#xff0c;机械&#xff0c;建筑金融&#xff0c;汽车&#xff0c;零售等各行各业&#xff0c;基…

【FastCAE源码阅读9】鼠标框选网格、节点的实现

一、VTK的框选支持类vtkInteractorStyleRubberBandPick FastCAE的鼠标事件交互类是PropPickerInteractionStyle&#xff0c;它扩展自vtkInteractorStyleRubberBandPick。vtkInteractorStyleRubberBandPick类可以实现鼠标框选物体&#xff0c;默认情况下按下键盘r键开启框选模式…

qt之扫码枪编码自动识别文本

一、前言 使用扫码枪输入扫码后&#xff0c;自动将编码转为文字或识别进入下一功能。 只是简单的实现了一种方式&#xff0c;并不适用于商业用途 二、环境 扫码枪免驱自动扫码编码打印到输入库的环境下 三、正文 本文介绍也是输入一种方式&#xff0c;不限于非得扫码识别…

YOLO-NAS:最高效的目标检测算法之一

YOLO-NAS目标检测 介绍 YOLO&#xff08;You Only Look Once&#xff09;是一种目标检测算法&#xff0c;它使用深度神经网络模型&#xff0c;特别是卷积神经网络&#xff0c;来实时检测和分类对象。该算法首次在2016年的论文《You Only Look Once&#xff1a;统一的实时目标检…

【Proteus仿真】【51单片机】拔河游戏设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED、动态数码管模块等。 主要功能&#xff1a; 系统运行后&#xff0c;指示灯处于中间位置&#xff0c;数码管显示得分0&#xff0c;当按下…

c++范围for语句

语法格式 for(declaration:expression)statement 基本使用 遍历输出 vector<int> nums { 1,2,3,4,5}; for (int num : nums) {num;cout << num << " "; } cout << endl; 遍历时修改 vector<int> nums { 1,2,3,4,5}; for (int&…