Ioc(Inversion of Control) 控制反转,DI(Dependncy Injection)依赖注入,其实是指同一种思想。举例说明:

  张三在某公司负责供水问题。有两种形式,第一种老板指定必须要买A公司的水,这样如果某天A公司不能再提供水了,需换别的公司供水时,张三必须请示老板才能做决定。第二种是老板只要求公司供水正常,不指定具体公司,这样换公司时,张三就不用通过老板再决定。其中第二种相较于第一种就体现了控制反转的思想,老板只对张三提出一个接口,要求供水,具体的操作由张三全权完成,将供水的控制权反转给了张三。

  在Spring中张三相当于一个xml格式的配置文件,领导是一个发送请求的bean,矿泉水公司是提供服务的另一个bean,XML起到一个中间连接的作用,当依赖发生变化时,只需要更改XML的依赖注入就可以实现服务变更。

  将上面例子转化为代码形式,如下:

//假设已经有个Water类,表示矿泉水
//按照领导决定供水公司方式
//首先创建一个矿泉水公司A,包括提供矿泉水服务的基本属性
public class WaterCompanyA {
private Water water ;
public Water getWater(){
return water;
};
}
//矿泉水公司B,也包括提供矿泉水服务
public class WaterCompanyB{
private Water water;
public Water getWater(){
return water;
};
}
//创建一个老板类,老板其实就是一个客户端程序,有需要矿泉水的请求
public class boss{
//假设与A签订了供水协约,实例化一个A公司
private WaterCompany wca = new WaterCompany();
public void needWater(){
wca.getWater();//A为其供水
}
}
//每次供水公司需要更换时,都需要更改Boss中的实例化对象
//请求服务与提供服务间的耦合性太强了,代码灵活性低
//按照由张三决定供水公司方式
//为实现Boss类不直接通过调用公司实体类来取得服务,需要设计一个供水公司接口
public interface IWaterCompany{
//供水服务
public Water getWater();
}
//A,B两家供水公司要想给Boss提供供水业务,就需要实现这个接口
public class WaterCompanyA implements IWaterCompany{
private Water water;
//实现接口中的抽象方法
public Water getWater(){
return water;
}
}
public class WaterCompanyB implements IWaterCompany{
private Water water;
//实现接口中的抽象方法
public Water getWater(){
return water;
}
}
//改写Boss类
public class Boss{
//接口属性
private IWaterCompany wcp;
public void needWater(){
getWcp().getWater();
} public IWaterCompany getWcp(){
return wcp;
}
//实现IWaterCompany接口的所有类实例都可作为参数
public void setWcp(IWaterCompany wcp){
this.wcp = wcp;
}
}
//改写的Boss勒种已经完全与AB公司解耦,只需通过别的方法将A或B注入给Boss即可
//一个测试类,注入A
public class TestClient{
public static void main() {
Boss boss = new Boss();
//注入A
boss.setWcp(new WaterCompanyA());
//得到供水服务
boss.needWater();
}
}
//上面的测试类就担当了张三的角色,在Spring中由XML配置文件代替

依赖注入的3种方式

1.接口注入--将要注入的内容置入到一个借口中,然后将其注入到它的实现类中,因为实现一个接口必须实现接口定义的所有方法。eg:

public interface IGetCompany {
//取得一家具体的公司
public IwaterCompany getCompany(IWaterCompany wcp);
}

当一个类实现了这几个接口,就意味着它被注入了getCompany这个方法,且必须实现它哪怕是空实现,如下面这个实现类:

public class GetCompanyImpl implements IGetCompany{
//实现getCompany方法,且必须实现,它是IgetCompany注入给它的一个方法
public IWtaerCompany getCompany(IWaterCompany wcp){
return wcp;
}
}

2.set注入--注入者通过调用setter方法将一个对象注入进去,如

public class Boss{
//以接口为属性
private IWaterCompany wcp;
public void needWater(){
//得到供水服务
getWcp().getWater();
}
public IWtaerCompany getWcp(){
return wcp;
}
//实现IWaterCompany接口的所有类的实例都可以作为参数传递进来
public void setWcp(IWaterCompany wcp){
 this.wcp = wcp;

}
//Boss类中含有一个wcp属性,要想给这个属性注入一个具体的对象值,那么就可以通过setWcp这个方法做到,eg
public class TestClient{
public static void main(){
Boss boss= new Boss();
//先实例化一个WaterCompanyA独享,然后将它注入进去
boss.setWcp(new WaterCompanyA());
//得到A公司供水服务
boss.needWater();
}
}

3.构造注入--是通过一个带参的构造函数将一个对象注入进去。上面的Boss类是通过set方法进行依赖注入的,那么也很容易改为构造注入方法,eg:

public class Boss{
private IWaterCompany wcp;
//构造注入
public Boss(IWaterCompany wcp){
this.wcp=wcp;
}
}

该类中,直接将参数写进了构造函数中,在实例化Boss类的时候,就可以将一个IWtaerCompany实例注入给Boss。这个过程就叫构造注入

最新文章

  1. 自定义 checkbox 新玩法 ?
  2. selenium如何跳转到iframe
  3. UESTC 901 方老师抢银行 --Tarjan求强连通分量
  4. android 开发工具(android studio)
  5. POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))
  6. Java类加载器加载类顺序
  7. Android实例-MotionSensor加速度(XE8+小米2)
  8. Model Thinking1
  9. [Head First Python]4.读取文件datafile.txt, 去除两边空格, 存储到列表,从列表格式化(nester.py)后输出到文件man.out,other.out
  10. HOJ1008
  11. 区间dp模型之括号匹配打印路径 poj(1141)
  12. 100+ 值得收藏的 Web 开发资源
  13. UE4 Fade out Mesh
  14. Caused by: java.net.SocketException: Broken pipe
  15. 【BZOJ1975】【SDOI2010】魔法猪学院(搜索,A*,贪心)
  16. 20175221 《Java程序设计》第8周学习总结
  17. 这20个Docker Command,有几个是你会的?
  18. List集合remove元素的问题
  19. 【NOIP 2015】Day2 T3 运输计划
  20. gsl库安装

热门文章

  1. CentOS6.9上安装FreeSWITCH1.6.19
  2. 关于java@Override错误
  3. 详细讲解:通过composer安装TP5.1(Thinkphp5.1)
  4. C++ POD类型
  5. 基于LBS的多人聊天
  6. npy数据的保存与读取
  7. Java8函数之旅 (二) --Java8中的流
  8. 激活SQLPrompt7.4及以上版本
  9. caffe安装中opencv的各种库问题
  10. 知识总结和记录——HTML