Spring 依赖注入02

文章目录

    • 1. 核心概念
    • 2. 依赖注入的方式
    • 3. 构造函数注入
      • 3.1 构造函数注入的优点包括:
    • 4. 设值注入
      • 4.1 设值注入的特点和优点
      • 4.2 使用设值注入的注意事项
    • 5. 接口注入
      • 5.1 接口注入的基本概念:
      • 5.2 使用接口注入的注意事项:

依赖注入(Dependency Injection,DI)

1. 核心概念

是面向对象编程中的一种设计模式,它主要用于降低组件之间的耦合度,促进代码的可测试性和可维护性。在依赖注入中,对象的依赖关系不是在内部创建,而是由外部容器(比如 Spring 框架)在对象创建时将依赖对象注入进来。

  1. 依赖:一个对象依赖于另一个对象,如果它需要使用另一个对象的服务或者资源来完成自身的功能。例如,一个订单服务可能依赖于一个支付服务来完成支付功能。

  2. 注入:指的是将一个对象的依赖关系传递给另一个对象的过程。依赖注入有三种主要的实现方式:

2. 依赖注入的方式

  1. 构造函数注入(Constructor Injection):依赖通过对象的构造函数传入。
  2. 设值注入(Setter Injection):依赖通过对象的设值方法(setter 方法)传入。
  3. 接口注入(Interface Injection):依赖通过特定的接口方法传入。
  4. 控制反转(Inversion of Control,IoC):依赖注入通常与控制反转紧密相关。控制反转是一种设计原则,指的是将对象的创建、管理和关联的控制权从应用程序代码中反转到外部容器(比如 Spring 容器)中。依赖注入是实现控制反转的一种方式。

3. 构造函数注入

示例

public class UserService {private final UserRepository userRepository;// 构造函数注入public UserService(UserRepository userRepository) {this.userRepository = userRepository;}// 其他业务方法public void saveUser(User user) {userRepository.save(user);}// 可选的设值注入方法public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}
}

3.1 构造函数注入的优点包括:

  1. 明确性:通过构造函数明确地声明对象需要哪些依赖,提高了代码的可读性可理解性。、
  2. 不可变性:一旦对象被创建并注入了依赖,其依赖关系通常是不可变的,避免了在对象生命周期中的不必要变动。
  3. 线程安全:对象在创建时一次性注入所有依赖,避免了多线程环境下可能导致的并发问题。

4. 设值注入

设值注入(Setter Injection)是依赖注入(DI)的一种形式,它通过对象的公共设值方法(setter 方法)来注入依赖。在使用设值注入时,依赖关系不是通过对象的构造函数传入,而是在对象创建后,通过调用特定的设值方法来设置依赖。

public class UserService {private UserRepository userRepository;// 设值注入方法public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}// 其他业务方法public void saveUser(User user) {userRepository.save(user);}
}

4.1 设值注入的特点和优点

  1. 灵活性:与构造函数注入相比,设值注入允许在对象创建后动态地改变对象的依赖关系,因为依赖的设置是通过公共的 setter 方法完成的。
  2. 可选性:设值注入可以让某些依赖是可选的,即可以为某个依赖设置一个默认值,如果外部未提供,则使用默认值。
  3. 易于理解和维护:设值注入可以使对象的依赖关系更加明确,每个依赖可以有对应的设值方法,提高了代码的可读性和可维护性。

4.2 使用设值注入的注意事项

  1. 可选性和默认值:设值注入可以为某些依赖设置默认值,当外部未提供依赖时可以使用这些默认值。
  2. 顺序依赖:如果对象的某些依赖需要按顺序设置,设值注入可以更灵活地处理这种情况,因为可以根据具体的业务需求在合适的时间设置依赖。
  3. 不变性:设值注入使得对象在创建后可以动态地改变依赖关系,这在某些场景下可能带来不必要的复杂性和隐患,因此需要谨慎设计和使用。

5. 接口注入

接口注入(Interface Injection)是依赖注入(DI)的一种形式,它通过实现特定接口来实现依赖的注入。相较于常见的构造函数注入和设值注入,接口注入在现代框架和实践中较少使用,因为它具有一些局限性和复杂性,不如其他方式那样直观和灵活。

public interface DependencyInjector {void injectDependency(Object dependentObject);
}
public class MyDependencyInjector implements DependencyInjector {private MyDependency dependency;// 实现接口的注入方法@Overridepublic void injectDependency(Object dependentObject) {if (dependentObject instanceof DependentClass) {((DependentClass) dependentObject).setDependency(dependency);}}// 设置依赖对象的方法public void setDependency(MyDependency dependency) {this.dependency = dependency;}
}

5.1 接口注入的基本概念:

  1. 依赖注入方式:接口注入是通过实现特定接口的方式来注入依赖,该接口通常定义一个方法用于接收依赖对象。
  2. 接口定义:依赖注入的接口通常包括一个或多个方法,用于在对象创建后将依赖对象传递给实现类。
  3. 实现类:实现该接口的类需要提供方法的具体实现,以便接收依赖对象,并在适当的时机将其注入到对象中。

5.2 使用接口注入的注意事项:

  1. 复杂性和局限性:相较于构造函数注入和设值注入,接口注入需要定义接口和实现类,并且实现类需要显式地调用注入方法。这增加了代码的复杂性和依赖的耦合度。
  2. 可测试性:接口注入可能会影响代码的可测试性,因为依赖关系的设置通常需要在对象创建后进行,这可能会导致测试代码的编写和管理变得更加复杂。
  3. 现代框架实践:现代的依赖注入框架(如 Spring、Guice 等)通常更倾向于使用构造函数注入和设值注入,因为它们提供了更好的灵活性和清晰度。

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

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

相关文章

数据结构 —— B+树和B*树及MySQL底层引擎

数据结构 —— B树和B*树及MySQL底层引擎 B树B*树B树的应用B树在MySQL中的应用MyISAMInnoDB 我们之前学习了B树的基本原理,今天我们来看看B树的一些改良版本——B树和B*树。如果还没有了解过的小伙伴可以点击这里: https://blog.csdn.net/qq_67693066/ar…

【MySQL进阶之路 | 高级篇】MVCC三剑客:隐藏字段,Undo Log,ReadView

1. 再谈隔离级别 我们知道事务有四个隔离级别,可能存在三种并发问题: 在MySQL中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,如果仅从定义的角度来看,它并不能解决幻读问题。如果我们想要解…

Nacos-2.4.0最新版本docker镜像,本人亲自制作,部署十分方便,兼容postgresql最新版本17和16,奉献给大家了

基于Postgresql数据库存储的nacos最新版本2.4.0,采用docker镜像安装方式 因业务需要,为了让nacos支持postgresql,特意花了两天时间修改了源码,然后制作了docker镜像,如果你也在找支持postgresql的nacos最新版本,恭喜你,你来的正好~ nacos-2.4.0 postgresql的数据库脚本…

安宝特方案|解放双手,解决死角,AR带来质量监督新体验

AR质量监督 解放双手,解决死角 在当今制造业快速发展的背景下,质量监督成为确保产品高质量和完善的管理制度的关键环节。然而,传统的质量监督方式存在诸多挑战,如人工操作带来的效率低下、查岗不及时、摄像头死角等问题。 为了解…

本地部署,Whisper: 开源语音识别模型

目录 简介 特点 应用 使用方法 总结 GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak SupervisionRobust Speech Recognition via Large-Scale Weak Supervision - openai/whisperhttps://github.com/openai/whisper 简介 Whisper 是一个由 O…

GoogleCTF2023 Writeup

GoogleCTF2023 Writeup Misc NPC Crypto LEAST COMMON GENOMINATOR? Web UNDER-CONSTRUCTION NPC A friend handed me this map and told me that it will lead me to the flag. It is confusing me and I don’t know how to read it, can you help me out? Attach…

软件更新的双刃剑:从”微软蓝屏”事件看网络安全的挑战与对策

引言 原文链接 近日,一场由微软视窗系统软件更新引发的全球性"微软蓝屏"事件震惊了整个科技界。这次事件源于美国电脑安全技术公司"众击"提供的一个带有"缺陷"的软件更新,如同一颗隐形炸弹在全球范围内引爆,…

17.5【C语言】static的补充说明

static &#xff08;静态的) 作用&#xff1a;修饰局部变量&#xff0c;修饰全局变量&#xff0c;修饰函数 对比两段代码 #include <stdio.h> void test() {int a 5;a;printf("%d ", a); } int main() {int i 0;for(i0; i<5; i){test();}return 0; } …

高并发内存池——链表设计

自由链表类的设计 由于申请的空间块经过对齐之后大小至少为8&#xff0c;因此可以考虑在未被使用的内存块中取前8字节存储下一个空间的地址 FreeList类初步声明 class FreeList { private:void* _freelistnullptr; //自由链表头指针size_t _size0; //自由链表的长度size_t …

【Django】anaconda环境变量配置及配置python虚拟环境

文章目录 配置环境变量配置python虚拟环境查看conda源并配置国内源在虚拟环境中安装django 配置环境变量 control sysdm.cpl,,3笔者anaconda安装目录为C:\ProgramData\anaconda3 那么需要加入path中的有如下三个 C:\ProgramData\anaconda3 C:\ProgramData\anaconda3\Scripts C:…

最新风车IM即时聊天源码及完整视频教程2024年7月版

堡塔面板 试验性Centos/Ubuntu/Debian安装命令 独立运行环境&#xff08;py3.7&#xff09; 可能存在少量兼容性问题 不断优化中 curl -sSO http://io.bt.sy/install/install_panel.sh && bash install_panel.sh 1.宝塔环境如下: Nginx 1.20 Tomcat 8 MySQL 8.0 R…

Java 开发环境配置

1. 下载 JDK 直接在oracle 官网下载 https://www.oracle.com/java/technologies/downloads或者使用博主已经从oracle下载的 jdk21&#xff1a;https://download.csdn.net/download/u011171506/89585231jdk8&#xff1a;https://download.csdn.net/download/u011171506/8958523…

快醒醒,别睡了!...讲《数据分析pandas库》了—/—<4>

一、废话不多说&#xff0c;直接开讲 1、DataFrame的索引和切片 1.1 选择列 当想要获取 df 中某列数据时&#xff0c;只需要在 df 后面的方括号中指明要选择的列即可。如果是 一列&#xff0c;则只需要传入一个列名;如果是同时选择多列&#xff0c;则传入多个列名即可&#xf…

SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景 在 SAPUI5 中&#xff0c;Fragments 是一种轻量级的 UI 组件&#xff0c;类似于视图&#xff08;Views&#xff09;&#xff0c;但它们没有自己的控制器&#xff08;Controller&#xff09;。Fragments 通常用于定义可以在多个视图中重用的 UI 片段&#xff0c;从而提…

集成千兆网口(Gigabit Ethernet Port)的作用主要是提供高速的有线网络连接,其工作原理涉及以下几个关键点:

传输速率&#xff1a; 千兆网口支持的最高传输速率达到1 Gbps&#xff08;即每秒10亿位&#xff09;&#xff0c;是传统百兆网口&#xff08;100 Mbps&#xff09;的十倍速度。这使得它能够处理更大量、更高质量的数据传输。 数据传输效率&#xff1a; 千兆网口能显著提高局域…

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意&#xff1a;XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下&#xff0c;之后又将XML文件复制到相同的目录下&#xff0c;需要删除引用&am…

【机器学习】Python、NumPy和向量化的基础知识以及三者结合的用法和示例

引言 在机器学习中&#xff0c;NumPy是一个非常重要的库&#xff0c;特别是在进行向量化操作时。向量化是一种优化技术&#xff0c;可以显著提高数组计算的效率&#xff0c;特别是在处理大型数据集时。NumPy提供了丰富的数组运算功能&#xff0c;使得向量化操作变得简单高效 文…

驾驭代码的无形疆界:动态内存管理揭秘

目录 1.:为什么要有动态内存分配 2.malloc和free 2.1:malloc 2.2:free 3.calloc和realloc 3.1:calloc 3.1.1:代码1(malloc) 3.1.2:代码2(calloc) 3.2:realloc 3.2.1:原地扩容 3.2.2:异地扩容 3.2.3:代码1(原地扩容) 3.2.3:代码2(异地扩容) 4:常见的动态内存的错误…

掀桌子了!原来是咱们的大屏设计太酷,吓着前端开发老铁了

掀桌子了&#xff01;原来是咱们的大屏设计太酷&#xff0c;吓着前端开发老铁了 艾斯视觉观点认为&#xff1a;在软件开发的世界里&#xff0c;有时候创意和设计的火花会擦得特别亮&#xff0c;以至于让技术实现的伙伴们感到既兴奋又紧张。这不&#xff0c;我们的设计团队刚刚…

Vue的安装配置

1.安装node js Node.js — 在任何地方运行 JavaScript (nodejs.org) 2.测试nodejs是否安装成功 node -v npm -v3.通过npm 安装 vue npm install -g vue/cli4.测试vue是否安装成功 vue --version5.打开PyCharm&#xff0c;创建项目&#xff1a;flask-web vue create flask…