依赖注入原理(为什么需要依赖注入)

maven打包成第三方jar包且把pom依赖包打入进来的方法 主要介绍了maven打包成第三方jar包且把pom依赖包打入进来的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 立即下载

0. 前言

在软件工程领域,依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一。本文主要介绍依赖注入原理和常见的实现方式,重点在于介绍这种年轻的设计模式的适用场景及优势。

1. 为什么需要依赖注入

控制反转用于解耦,解的究竟是谁和谁的耦?这是我在最初了解依赖注入时候产生的第一个问题。

下面我引用Martin Flower在解释介绍注入时使用的一部分代码来说明这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MovieLister {
    private MovieFinder finder;

    public MovieLister() {
        finder = new MovieFinderImpl();
    }
    
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }
    ...
}

1
2
3
public interface MovieFinder {
    List findAll();
}

我们创建了一个名为MovieLister的类来提供需要的电影列表,它moviesDirectedBy方法提供根据导演名来搜索电影的方式。真正负责搜索电影的是实现了MovieFinder接口的MovieFinderImpl,我们的MovieLister类在构造函数中创建了一个MovieFinderImpl的对象。

目前看来,一切都不错。但是,当我们希望修改finder,将finder替换为一种新的实现时(比如为MovieFinder增加一个参数表明Movie数据的来源是哪个数据库),我们不仅需要修改MovieFinderImpl类,还需要修改我们MovieLister中创建MovieFinderImpl的代码。

这就是依赖注入要处理的耦合。这种在MovieLister中创建MovieFinderImpl的方式,使得MovieLister不仅仅依赖于MovieFinder这个接口,它还依赖于MovieListImpl这个实现。 这种在一个类中直接创建另一个类的对象的代码,和硬编码(hard-coded strings)以及硬编码的数字(magic numbers)一样,是一种导致耦合的坏味道,我们可以把这种坏味道称为硬初始化(hard init)。同时,我们也应该像记住硬编码一样记住,new(对象创建)是有毒的。

Hard Init带来的主要坏处有两个方面:1)上文所述的修改其实现时,需要修改创建处的代码;2)不便于测试,这种方式创建的类(上文中的MovieLister)无法单独被测试,其行为和MovieFinderImpl紧紧耦合在一起,同时,也会导致代码的可读性问题(“如果一段代码不便于测试,那么它一定不便于阅读。”)。

2. 依赖注入的实现方式

依赖注入其实并不神奇,我们日常的代码中很多都用到了依赖注入,但很少注意到它,也很少主动使用依赖注入进行解耦。这里我们简单介绍一下赖注入实现三种的方式。

2.1 构造函数注入(Contructor Injection)

这是我认为的最简单的依赖注入方式,我们修改一下上面代码中MovieList的构造函数,使得MovieFinderImpl的实现在MovieLister类之外创建。这样,MovieLister就只依赖于我们定义的MovieFinder接口,而不依赖于MovieFinder的实现了。

1
2
3
4
5
6
7
8
public class MovieLister {
    private MovieFinder finder;

    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }
    ...
}

2.2 setter注入

类似的,我们可以增加一个setter函数来传入创建好的MovieFinder对象,这样同样可以避免在MovieFinder中hard init这个对象。

1
2
3
4
5
6
public class MovieLister {
    s...
    public void setFinder(MovieFinder finder) {
        this.finder = finder;
    }
}

2.3 接口注入

接口注入使用接口来提供setter方法,其实现方式如下。
首先要创建一个注入使用的接口。

1
2
3
public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}

之后,我们让MovieLister实现这个接口。
1
2
3
4
5
6
7
class MovieLister implements InjectFinder {
    ...
    public void injectFinder(MovieFinder finder) {
      this.finder = finder;
    }
    ...
}

最后,我们需要根据不同的框架创建被依赖的MovieFinder的实现。

3. 最后

依赖注入降低了依赖和被依赖类型间的耦合,在修改被依赖的类型实现时,不需要修改依赖类型的实现,同时,对于依赖类型的测试,可以更方便的使用mocking object替代原有的被依赖类型,以达到对依赖对象独立进行单元测试的目的。

最后需要注意的是,依赖注入只是控制反转的一种实现方式。控制反转还有一种常见的实现方式称为依赖查找。

参考

  1. Inversion of Control Containers and the Dependency Injection pattern
  2. How to Think About the “new” Operator with Respect to Unit Testing
  3. 依赖注入
挣脱枷锁:网页禁止复制/F12失效/右键失灵时的破局之道 大家在网上冲浪的否遇到过这种情况?急需网页上的一段关键信息、一段优美的文字、一个重要的代码片段,或者只是想收藏某篇文章,却发现:文本选择被阻止,右键菜单被禁用,开发者工具(F12)被屏蔽,查看源代码(Ctrl+U)失效?本文会有力解决这些封锁。 阅读详情

相关推荐

Vivado静态时序分析学习笔记(1)

静态时序分析分为片内时序分析(寄存器与寄存器之间的时序关系)和片外时序分析(IO时序分析)。(1)建立时间 setup time在时钟事件(上升沿/下降沿)发生之前数据信号应保持稳定的时间。把实际电路抽象成前级D触发器+组合逻辑+后级D触发器。

Fantaasky的博客 4375

spring——依赖注入原理及注入方式

总结来说,依赖注入的原理是通过将对象的依赖关系由外部容器来管理和注入,从而解耦组件之间的依赖关系,提高代码的灵活性、可维护性和可测试性。是通过在对象的构造函数、属性或方法中注入所依赖的对象,而不是在对象内部创建或获取依赖对象。这样,对象的依赖关系由外部容器来管理,对象只需要关注自身的核心功能,而不需要关心如何获取依赖对象。(6)使用目标对象:完成依赖注入后,可以通过目标对象的其他方法或属性来使用注入的依赖对象。🟠(1)定义对象的依赖属性:在目标对象中定义一个或多个私有属性,用于存储依赖对象的引用。

yangqiqi1997的博客 4458

win10系统下使用Mask_Rcnn训练自己的数据

版权所有,翻版必究。https://mp.youkuaiyun.com/console/editor/html/106094147 运行环境:WIN10,pycharm,相应的CUDA,CUDNN,tensorflow1.15.0,tensorflow-gpu-1.14.0,Anaconda3 第一步:Mask RCNN开源项目:https://github.com/matterport/Mask_RCNN 第一步:数据准备 首先安装labelme进行数据的标注。安装方法pip install labe

fightingxyz的博客 1750

依赖注入的原理

什么是依赖注入 依赖注入是实现程序解耦的一种方式。如果通过百度搜索可以找到如下答案: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。 看完之后发现更晕了~~...

Outlier的博客 1712

SAP 运费处理方式

从直接的处理方式上看,情况1/2/3可以将运费记账到物料成本中,但情况4/5/6是直接记账到成本对象中,具体是要体现在损益表中,还是要结转到物料成本中,可依据业务要求进行好处理。如果体现在损益表中,不需要多过多额外的操作,如果要体现在物料成本中心,则需要再进行一系列的处理,最终将金额结转到物料成本中。因为在创建采购订单时不知道具体运费,可以不维护运费,只需要维护材料价格。:创建采购订单时,运费是由供应商承担,很多时候是包含在材料报价中,这种情况不需要专门针对运费进行处理,材料价格中已包含运费。

weixin_44506537的博客 3371

ArduPilot 的 RTOS 选择:为何 ChibiOS 成为现代飞控的首选

本文深入探讨了ArduPilot选择ChibiOS作为现代飞控首选RTOS的原因。通过对比FreeRTOS和NuttX,ChibiOS凭借其50ns中断响应、1.2μs上下文切换时间和高效的资源管理脱颖而出,特别适合处理无人机飞控中的高频传感器融合和实时控制任务。文章还详细分析了ChibiOS在STM32硬件上的优化实践及其在无人机开发中的显著优势。

weixin_29161719的博客 567

什么是DI(依赖注入),依赖注入的原理

这篇文章主要介绍了Spring当中的依赖注入(DI),以及他的简单实现原理,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

怪咖@的博客 1万+

一分钟了解 “提示词工程”、“上下文工程”、“驾驭工程”

在大模型刚刚进入大众视野的初期,开发者面临的最大挑战是如何让模型听懂人类的指令。这一阶段被称为提示词工程时代。其核心思想非常直观:通过精心设计输入的文本提示,引导模型输出符合预期的结果。这一时期的开发者更像是“提示词巫师”,他们热衷于寻找所谓的“魔法咒语”。典型的技巧包括角色设定、思维链、少样本学习以及输出格式约束。例如,仅仅在问题前加上一句“请一步步思考”,模型的推理能力往往就能得到显著提升。然而,随着应用场景的复杂化,提示词工程的局限性逐渐暴露。

h a 6 6 6 c k 为 你解决复杂难题! 568

深入理解依赖注入

依赖注入(Dependency Injection,简称DI)是一种实现控制反转(Inversion of Control,简称IoC)的技术。在面向对象编程中,类的依赖关系通常是通过在类内部直接创建依赖对象来实现的,这种方式会导致代码之间的耦合度很高。而依赖注入则是将依赖对象的创建和绑定的过程交给容器来完成,从而实现了类的依赖关系和类本身的解耦。

果酱 の 博客 1469

LLC电路细讲笔记(二)LLC谐振转换器:频率、增益与Q值的详细探讨

这本电子书通过详细分析LLC谐振转换器的工作原理、等效电路和增益公式,帮助读者深入理解如何设计和优化谐振转换器系统。通过这些公式和设计方法,工程师可以根据不同的应用需求调整参数,实现高效的电能转换。

weixin_43199439的博客 6873

2026年最值得学习的十大 SAP 开发技术

在这辞旧迎新之际,我想和大家聊聊我心中的2026年我仍然愿意持续投入时间去学习的一些 SAP 开发技术。因为笔者水平和视野局限,加上这份清单有笔者主观兴趣爱好在内,可能大家对清单上罗列的技术有不同意见,欢迎大家在评论区发表自己的见解。下面是笔者列出的十个技术方向,排名不分先后。因为精力有限,2026年我很可能只会选择其中一两个自己最感兴趣的方向去深耕。每项技术后面都提供了链接,方便大家看完就开始学习。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1518

Spring 依赖注入概述、使用以及原理解析

我们本文主要来介绍依赖注入的使用示例及其原理 依赖注入(Dependency Injection,简称DI)是一种设计模式,它用于实现对象之间的松散耦合。在依赖注入中,一个对象不再负责创建或查找它所依赖的对象,而是将这些依赖关系通过外部传递进来,外部指的就是 IoC 容器,IoC 容器负责对象的创建、管理和注入,我们也常说 DI 是实现 IoC 的一种具体技术。这种方式有助于提高代码的可维护性、可测试性,同时降低了组件之间的耦合度。

MarkusZhang的博客 2182

1位2路选择器设计

1位2路选择器设计

好好学习,天天向上 3576

Spring 依赖注入原理

有时所在项目忙于业务快速迭代,只知道如何应用框架组件,底层原理却忽略了,框架许多精妙设计没掌握到。每天重复流水线工作,业务层面有所提升,但技术原地不动,每次热情高涨探索底层实现,由于种种原因,坚持没多久就放弃了。为了解开放弃探索小伙伴们心中疑惑,本人花了一些时间研究了底层实现。此次分享学习心得为Spring 依赖注入原理,在实际项目中最常见的依赖注入场景,跨业务注解服务互相调用,配置文件引用第三方服务时信息配置。 一 什么是依赖注入 通过类setXxx函数,有参构造函数或注解形式为类的成员属性附上值

370

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

PHP依赖注入的原理

PHP中的依赖注入(Dependency Injection,简称DI)是一种设计模式,旨在解耦和管理对象之间的依赖关系,使得代码更加灵活、可测试和可维护。

sheji888的专栏 1330

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Spring中依赖注入原理解析

依赖注入是Spring框架的核心功能之一,通过依赖注入可以实现组件之间的解耦,使得代码更加灵活和可维护。在Spring中,依赖注入是通过容器来实现的,容器负责管理组件之间的依赖关系,将依赖关系注入到组件中。依赖注入的原理主要是通过反射和动态代理来实现的,通过这两种技术,Spring可以实现自动注入依赖对象,从而实现依赖注入的功能。希望本文对大家理解Spring中的依赖注入原理有所帮助,欢迎大家多多交流和探讨。

dzend的专栏 707

@Autowired依赖注入的原理介绍

本文介绍了Spring框架中的@Autowired注解及其实现原理。@Autowired用于自动注入依赖,支持字段、构造函数、方法和参数注入,默认按类型匹配Bean。当存在多个同类型Bean时,可通过@Qualifier指定名称或使用@Primary标记首选Bean。文章还对比了替代方案:Java标准的@Inject(需配合@Named)、构造函数注入(推荐最佳实践)和JNDI规范的@Resource(按名称匹配)。这些依赖注入方式降低了代码耦合度,便于测试和维护,使开发者能专注于业务逻辑实现。

weixin_50055999的博客 1498

容器与依赖注入的原理

容器与依赖注入的原理 1.任何的URL访问,最终都是定位到控制器,由控制器中某个具体方法去执行 2.一个控制器对应一个类,如果这些类需要进行统一管理怎么办? 解决办法:用容器进行类管理。 容器不仅可以管理类,还可以将类的实例(对象)做为参数,传递给类方法进行调用,就会自动触发依赖注入 3.依赖注入:将对象类型的数据,以参数的方式传到方法的参数列表中。(将一个类中的对象传递到另一个类的方法中的技术)...

weixin_43947156的博客 747

四、Spring依赖注入原理分析

spring ioc bean 注册和实例化流程

追梦的土豆的博客 1105

laravel 依赖注入原理理解

作为一个进入职场五年的职场菜鸟,讲述如何进阶成为一个职场大神的进阶之路

Jessica_zhe的博客 2749

Spring源码剖析——依赖注入实现原理

引言  在之前的 Spring源码剖析——核心IOC容器原理这篇文章中,已经详细介绍了在Spring当中我们配置的Bean是怎样被Spring解析和管理的,我们配置的那些Bean经过 载入 、解析 和 注册 这三个过程后,在框架内部被抽象封装成BeanDefinition这种类型,最终所有的BeanDefinition交由BeanFactory当中的definitionMap统一管理起来(如果对该过

拂晓的专栏 4万+

依赖注入原理(简单易懂)

DI 依赖注入是 Spring 框架的核心特性,通过解耦组件依赖,提升了代码的可维护性和可测试性。掌握三种注入方式(构造器、setter、注解)的适用场景和最佳实践,是深入学习 Spring 的关键。在实际开发中,推荐以注解注入为主,结合 Spring Boot 的自动配置,简化开发流程,提高效率。

2403_87486006的博客 1641

Spring @Value注解的依赖注入实现原理

摘要: Spring的@Value注解通过依赖注入实现属性赋值,支持静态值和配置文件占位符(如${key})。其核心原理是通过InstantiationAwareBeanPostProcessor在Bean实例化前处理注解,解析字段的@Value标记,动态替换占位符并生成PropertyValues。实现分为四步:1)定义注解;2)扩展处理器接口;3)实现解析逻辑(扫描字段、处理占位符);4)集成到Bean生命周期(通过AbstractAutowireCapableBeanFactory调用)。代码示例展示

几许的博客 1560

Spring-依赖注入原理

使用构造器注入使用属性setter方法注入使用Field注入(用于注解方式) 注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。 1.手工装配依赖对象2.自动装配依赖对象 在Spring学习笔记(3)中剖析了Spring管理Bean的原理,下面解释下Spring依赖注入的原理 在进行依赖注入时,我们的配置文件如...

liberty12345678的专栏 3924

依赖注入原理

转: 依赖注入原理 依赖注入原理 发表于 2015-08-01   |   分类于 Software Engineering   |   3条评论 0. 前言 在软件工程领域,依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一。本文主要介绍依赖注入原理和常见的实现方式,重点

wxx614817的专栏 548
上一篇: android native 和 H5 的交互
下一篇: viewpager中彻底性动态添加、删除Fragment
MrCoderr
博客等级 码龄12年 39粉丝 48原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值