控制反转(IOC)和依赖注入(DI)的区别
IOC inversion of control 控制反转
DI Dependency Injection 依赖注入
要理解这两个概念,首先要搞清楚以下几个问题:
- 参与者都有谁?
- 依赖:谁依赖于谁?为什么需要依赖?
- 注入:谁注入于谁?到底注入什么?
- 控制反转:谁控制谁?控制什么?为何叫反转(有反转就应该有正转了)?
- 依赖注入和控制反转是同一概念吗?
下面就来简要的回答一下上述问题,把这些问题搞明白了,IoC/DI也就明白了。
(1)参与者都有谁:
一般有三方参与者,一个是某个对象;一个是IoC/DI的容器;另一个是某个对象的外部资源。
又要名词解释一下,某个对象指的就是任意的、普通的Java对象; IoC/DI的容器简单点说就是指用来实现IoC/DI功能的一个框架程序;对象的外部资源指的就是对象需要的,但是是从对象外部获取的,都统称资源,比如:对象需要的其它对象、或者是对象需要的文件资源等等。
(2)谁依赖于谁:
当然是某个对象依赖于IoC/DI的容器
(3)为什么需要依赖:
对象需要IoC/DI的容器来提供对象需要的外部资源
(4)谁注入于谁:
很明显是IoC/DI的容器 注入 某个对象
(5)到底注入什么:
就是注入某个对象所需要的外部资源
(6)谁控制谁:
当然是IoC/DI的容器来控制对象了
(7)控制什么:
主要是控制对象实例的创建
(8)为何叫反转:
反转是相对于正向而言的,那么什么算是正向的呢?考虑一下常规情况下的应用程序,如果要在A里面使用C,你会怎么做呢?当然是直接去创建C的对象,也就是说,是在A类中主动去获取所需要的外部资源C,这种情况被称为正向的。那么什么是反向呢?就是A类不再主动去获取C,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中。
用图例来说明一下,先看没有IoC/DI的时候,常规的A类使用C类的示意图,如图7所示:
图7 常规A使用C示意图
当有了IoC/DI的容器后,A类不再主动去创建C了,如图8所示:
图8 A类不再主动创建C
而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中,如图9所示:
图9 有IoC/DI容器后程序结构示意图
(9)依赖注入和控制反转是同一概念吗?
根据上面的讲述,应该能看出来,依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
(10)小结一下:
其实IoC/DI对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC/DI容器来创建并注入它所需要的资源了。
这么小小的一个改变其实是编程思想的一个大进步,这样就有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活
(11)接下演示一下依赖注入机制的过程
package com.zj.ioc.di.ctor;
import com.zj.ioc.di.Content;
public class MyBusiness {
private Content myContent;
public MyBusiness(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
}
|
package com.zj.ioc.di.ctor;
import com.zj.ioc.di.Content;
public class MyBusiness {
private Content myContent;
public MyBusiness(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
}
|
package com.zj.ioc.di.iface;
import com.zj.ioc.di.Content;
public interface InContent {
void createContent(Content content);
}
|
package com.zj.ioc.di.iface;
import com.zj.ioc.di.Content;
public interface InContent {
void createContent(Content content);
}
|
代码6
接口注入(Interface Injection)MyBusiness.java
package com.zj.ioc.di.iface;
import com.zj.ioc.di.Content;
public class MyBusiness implements InContent{
private Content myContent;
public void createContent(Content content) {
myContent = content;
}
public void doBusniess(){
myContent.BusniessContent();
}
public void doAnotherBusniess(){
myContent.AnotherBusniessContent();
}
}
|
控制反转(IOC)和依赖注入(DI)的区别的更多相关文章
- 控制反转IOC与依赖注入DI
理解 IOC http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例 的http:// ...
- 控制反转(Ioc)和依赖注入(DI)
控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...
- iOS控制反转(IoC)与依赖注入(DI)的实现
背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大 ...
- 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。
轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战 ...
- 控制反转IOC与依赖注入DI【转】
转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...
- 【转载】浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)
原文地址 http://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...
- 控制反转IOC与依赖注入DI - 理论篇
学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...
- 依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)
原文: https://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...
- 20181123_控制反转(IOC)和依赖注入(DI)
一. 控制反转和依赖注入: 控制反转的前提, 是依赖倒置原则, 系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖 (依赖抽象,而不是细节) 如果要想做到控制反转(IOC), 就必须要使 ...
- Spring框架学习笔记(1)——控制反转IOC与依赖注入DI
Spring框架的主要作用,就是提供了一个容器,使用该容器就可以创建并管理对象.比如说Dao类等,又或者是具有多依赖关系的类(Student类中包含有Teacher类的成员变量) Spring有两个核 ...
随机推荐
- 重新拷贝 新项目 发现不显示 原来是 paramiko 没有装
proxy pass 端口换成 另一个 跟原来的不冲突 [root@ayibang-server soft_ware]# cp s10day11/demo.* s10ops/[root@ayibang ...
- linux下如何启动/停止/重启mysql:
一.启动方式1.使用linux命令service 启动:service mysqld start2.使用 mysqld 脚本启动:/etc/inint.d/mysqld start3.使用 safe_ ...
- string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- Hadoop学习笔记: sqoop配置与使用
sqoop即SQL-to-Hadoop,是一个把数据从关系型数据库导入到Hadoop系统中的工具(HDFS,HIVE和HBase),也可以将数据从Hadoop导入到关系型数据库.本文以sqoop 1. ...
- iOS -Swift 3.0 -Array(数组与可变数组相关属性及用法)
// // ViewController.swift // Swift-Array // // Created by luorende on 16/9/12. // Copyright © 2016年 ...
- 使用NSURLSession请求需要AD认证的HTTPS服务器
关键代码:使用后台下载PDF文件 - (void)startDownloadPDF{ NSURLSession *session = [self session]; NSString *downloa ...
- JAVA-语法-运算符
1.赋值运算符 = (优先级较低) 2.算数运算符 + — * / % 3.字符串连接运算 + (把其他类型转成字符串并和字符串类型进行连接) 4.扩展赋值运算符 += — ...
- how to use automapper in c#, from cf~
[DataContract] public class GroupDto { [DataMember] public int id { get; set; } [DataMember] public ...
- hdu5354 Bipartite Graph
分治+并查集.假设要求[L,mid]的答案,那么很明显,如果一条边的两个端点都>mid的话或者一个端点>mid一个端点<L,说明询问[L,mid]这个区间中任何一点时候,这一条边都是 ...
- 深度解析 Java 内存原型
一.Java 虚拟机内存原型 寄存器:我们在程序中无法控制. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在 堆中. 堆:存放用 new 产生的数据. 静态域:存放在对象中用 ...