一、依赖注入的概念了解

介绍依赖注入(di),首先要先了解一个概念——即控制反转(ioc)。

控制反转是面向对象编程的一种设计原则,可以用来减低计算机代码之间的耦合度。在传统的应用程序中,都是程序员手动在类的内部创建需要依赖的对象,而这种方式经常会导致类与类之间的高度耦合,难以测试。而当有了ioc容器之后,类把创建和查找依赖对象的权限都交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这一方便与测试,同时也利用功能的复用和代码结构的灵活。

di(dependency injection),即“依赖注入”。ioc是一个很大的概念,可以用不同的方式实现。其主要表现形式主要有两种,一种是依赖查找,另外一种就是依赖注入了,依赖注入即组件不做定位查询,只提供普通的java方法让容器去决定依赖关系。容器全权负责组件的装配,它会把符合依赖关系的对象通过javabean属性或者构造函数传递给需要的对象。通过javabean属性注射依赖关系的做法称为设置方法注入(setter injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(constructor injection)。

二、依赖注入的优点、实现

在我们的实际生产中,任何一个应用都是由许多类组成,这些类相互之间按照协作来完成特定的业务逻辑。按照传统的方式,每个对象负责管理与自己相互协作的对象(即它所依赖的对象)的引用,这将会导致高度耦合和难以测试的代码。

举个例子,下面代码中的lecturer类,只能执行讲授高等数学课的任务

public class lecturer implements teacher {

private advancedmathematicstask task;

public lecturer() {

// 在这里与 mathlessonqeust紧耦合

this.task = new advancedmathematicstask();

}

public void lecturelesson() {

task.lecture();

}

}

可以从上面的代码中看出,lecturer在构造函数中创建了advancedmathematicstask,这使得lecturer和advancedmathematicstask紧密地耦合到了一次,因此极大地限制了这个讲师的授课能力,如果这学期需要以为讲授高等数学的老师,那么这位讲师可以立刻就任,都是如果开一门线性代数,或者统计学,那么这位讲师就爱莫能助了。

更加糟糕的是,为这个lecturer编写单元测试的时候将格外的困难。在这样的代码中,你必须保证当讲师的lecturelesson()方法被调用的时候,task的lecture()方法也要被调用。但是没有一个简单明了的方式能够实现这一点。很遗憾,lecturer将无法进行测试。

而通过di,对象的依赖关系将由系统中负责协调各对象的第三方组件来创建对象的时候进行设定。对象无需自行创建或管理他们的依赖关系。

下面我们通过代码,展示这一点

public class professor implements teacher {

private task task;

public professor(task task) {

// quest 被注入进来

this.task = task;

}

public void lecturelesson() {

ask.lecture();

}

}

从上面代码,我们可以看到与之间不同,professor没有自行创建授课任务,而是在构造器中把授课任务作为参数传入。这是依赖注入的方式之一,即前面提到的构造器注入。

更重要的是,传入的任务类型是task,也就是所有授课任务都必须实现同一个接口。所以,professor可以响应advancedmathematicstask、linearalgebratask、statisticstask等任意task的实现。

这里的要点是professor没有与任何特定的task实现发生耦合,对它来说,被要求讲授的课只要实现了task接口,那么具体是哪门课就无所谓了。这就是di所带来的最大收益——松耦合。如果一个对象只通过接口(而不是具体实现或初始化过程)来表明依赖关系,那么这种依赖就能够在对象本身毫不知情的情况下,用不同的具体实现进行替换。

对依赖进行替换的一个最采用方法就是在测试的时候使用mock实现。我们无法充分地测试lecturer,因为它是紧耦合的;但是可以轻松地测试professor,只需要给它一个task的mock实现即可,如下面代码所示

import static org.mockito.mockito.*;

import org.junit.test;

public class professortext {

@test

public void professorshouldlecturelesson() {

task mocktask = mock(task.class); // 创建 mock task

professor professor = new professor(mocktask); // 注入 mock task

professor.lecturelesson();

verify(mocktask, times(1)).lecture(); // 验证mocktask实现的lecture()方法仅被调用一次

}

}

所以我们可以从上面的例子看出,di能够让相互协作的软件组件保持松散耦合。

小结

di是组装应用的一种方式,借助这种方式对象无需知道依赖来自何处或者依赖的实现方式。不同于自己获取依赖对象,对象会在运行期赋予它们所依赖的对象。依赖对象通常会通过接口了解所注入的对象,这样的话就能确保低耦合。

文章参考

《spring in action》

希望与广大网友互动??

点此进行留言吧!

java 注入依赖_依赖注入(Dependency Injection)相关推荐

  1. java 字段构造函数_依赖注入–字段vs构造函数vs方法

    java 字段构造函数 嗨,今天,我想简短地讨论将依赖项注入您的类的不同方式. 通常,您有以下三种注射方法 直接进入字段/属性 通过显式的setter方法 通过显式的构造函数参数 现场注入 这种类型的 ...

  2. Spring MVC快速教程:依赖注入 Spring MVC Fast Tutorial: Dependency Injection

    What are we going to build? Use singletons of CarManager and BrandManager instead of creating multip ...

  3. mockito手动注入依赖_依赖注入–手动方式

    mockito手动注入依赖 依赖注入是一种将行为与依赖解决方案分开的技术. 用简单的话来说,它使开发人员可以定义具有特定功能的类,这些功能取决于各种协作者,而不必定义如何获取对这些协作者的引用. 以此 ...

  4. mysql报错注入实战_手工注入——MySQL手工注入实战和分析

    今天进行了MySQL手工注入实战,分享一下自己的实战过程和总结,这里环境使用的是墨者学院的在线靶场.话不多说,咱们直接开始. 第一步,判断注入点 通过 ' 和构造 and 1=1 和 and 1=2 ...

  5. 所需依赖_注意细节,阿里架构师一文详解SpringDI的四种依赖注入方式

    SpringDI(依赖注入) 一.DI概述 Dependency Injection即为依赖注入,简称DI. 简单来说,在Spring创建对象的同时,为其属性赋值,称之为依赖注入. 形象来说,组件之间 ...

  6. IoC容器和Dependency Injection模式

    注:本文转自http://insights.thoughtworkers.org/injection/,请尊重译者的劳动成果,转载需注明出处. 2017年3月3日 by Martin Fowler L ...

  7. IoC 容器和 Dependency Injection 模式[转]

    转自:插图版<IoC 容器和Dependency Injection 模式> 原文地址:Inversion of Control Containers and the Dependency ...

  8. IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern

    原文链接:http://www.martinfowler.com/articles/injection.html 文末有中文翻译版本,martinfowler上有提供中文版的pdf,也可以自行下载 中 ...

  9. angular示例_Angular Dependency Injection用示例解释

    angular示例 什么是依赖注入? (What is Dependency Injection?) 动机 (Motivation) Dependency Injection is often mor ...

最新文章

  1. Python中通过PyPDF2实现PDF拆分
  2. Android深入浅出系列之实例应用—弹出消息Toast对象的使用自定义方式(二)
  3. YII2集成GOAOP,实现面向方面编程!
  4. JVM PermGen –您在哪里?
  5. “约见”面试官系列之常见面试题第十五篇之jsonp(建议收藏)
  6. java 重构 if else_项目中的if else太多了,该怎么重构?
  7. pythongui显示图片_opencv2.4.13+python2.7学习笔记--opencv中的Gui特性--图片:读图像,显示图像,保存图像...
  8. lab 2 EIGRP Default Route
  9. leetcode - 279. 完全平方数
  10. 论文盘点:CVPR 2018 Top 20,华人发明的SENet居首!
  11. 红橙Darren视频笔记 界面优化与屏幕适配(下)
  12. 实际操作更改Linux启动模式
  13. python调用摄像头录制视频_Python OpenCV使用摄像头捕获视频
  14. base64解码_一份简明的 Base64 原理解析
  15. 设计模式入门进阶深入书籍汇总
  16. GitHub远程拉取仓库项目提示Please use a personal access token instead.解决方法
  17. Linux生成掩码的计算,谈子网掩码及其计算
  18. PASCAL VOC2012 数据集讲解与制作自己的数据集
  19. const int *,const int * const和int const *之间的区别
  20. DirectoryInfo 类

热门文章

  1. 使用Sonarqube扫描Javascript代码
  2. 取消管理员取得所有权_利用管理员取得所有权删除顽固文件
  3. 提高网速最好办法是把windows的20%预留带宽提出来-设置限制可保留带宽提速
  4. 3060显卡 吃鸡 1080P 全高特效 1h 温度 内存占用 显存占用
  5. TWaver推智能手表挑战华为苹果
  6. 程序员的时代红利快消失了,我要抓住它
  7. 一文说清DC-DC BUCK电路(非常详细)
  8. python天涯帖子_python 网络爬虫(一)爬取天涯论坛评论
  9. 如何用python读取表格_如何使用Python读取excel文件?(代码示例)
  10. 把大象装冰箱,要几个步骤?