提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
大概内容:本文我会为大家介绍如何理解IoC和Di,已经为什么Spring会被叫作包含众多工具方法的IoC容器…
我们要理解IoC,首先要明确,什么是IoC?
IoC-------Inversion of Control,翻译过来即为"控制反转",又可以叫做控制权反转.
知道了什么是控制权反转,我们还不着急去理解它,更重要的是,你要先明确一个点,
IoC是一个思想!
IoC是一个思想!
IoC是一个思想!
明确了这一点之后,我们才能真正开始去理解IoC.
首先,控制权反转,
何为控制权?
顾名思义,控制权,
在现实生活中,就是由你来掌控管理的,比如你的手机,你的电脑.
在计算机中,控制权即对对象,又或者文件资源的控制管理.
何为反转?
也不难理解,你可以看成控制权转移,即本来控制权由A来决定,现在转移给B.
如果只是这么说一下,我相信大家肯定是还不难理解什么是控制权反转,更不能理解为什么需要控制权反转,所以接下来我会举个理解帮助大家进一步的去理解控制权反转.
首先我们创建一个Phone类(手机),依赖于MotherBoard类(主板),而主板类又依赖于Chip类(芯片)
手机类
package mobile_phone;
public class Phone {
private MotherBoard motherBoard;
public Phone(int size){
motherBoard=new MotherBoard(size);
}
public void init(){
System.out.println("Phone is OK");
motherBoard.init();
}
public static void main(String[] args) {
Phone phone=new Phone(15);
phone.init();
}
}
可以看到,在上面代码中,new 了手机类依赖的主板类,并且传了芯片需要的大小.
主板类
package mobile_phone;
//主板类
public class MotherBoard {
private Chip chip;
public MotherBoard(int size){
chip=new Chip(size);
}
public void init(){
System.out.println("motherBoard is OK!");
chip.init();
}
}
同样的,这里也是由主板类主动创建其依赖的芯片类.并且给其传参.
芯片类
package mobile_phone;
//芯片类
public class Chip {
private int size=0;
public Chip(int size){
this.size=size;
}
public void init(){
System.out.println("chip is OK and chipSize is:"+this.size);
}
}
对象的创建顺序是先有手机类,再有主板类,最后创建芯片类对象.
运行后的打印结果
其中根据代码不难发现它们的依赖关系,在手机类中,因为其需要主板,因此要依赖主板类,所以创建了主板类(new …),且进行了初始化,同样的,主板类依赖于芯片类,因此同样创建了芯片类,进行初始化.
如果此时我们修改芯片类的代码,让其能提供芯片的产地
就可以发现,主板类报错了
这是因为主板类中new 一个芯片对象时,没有提供相应参数,
因此需要进行修改,同样的,主板的上一级也会发生相似的错误,需要你为其提供相应参数,由此我们就可以得出一个结论,
传统的构建方法每个依赖的类之间耦合度较高,如果一个被依赖的类发生改变,那么依赖其的类很可能也需要进行修改,导致工程量较大,即付出成本较大.
我们把类的创建交给第三者,即不直接在某个类中创建自己的下级类了(即自己依赖的类),而是将原来由自己创建这种方法变成由第三者创建并且为我们传入(即为我们提供),提供这种方式,哪怕下级类发生了改变,当前类也不需要进行任何修改,这样就能实现程序的解耦.
手机类
package mobile_phone2;
public class Phone {
private MotherBoard motherBoard;
public Phone(MotherBoard motherBoard){
this.motherBoard=motherBoard;
}
public void init(){
System.out.println("Phone is OK!");
motherBoard.init();
}
}
主板类
package mobile_phone2;
public class MotherBoard {
private Chip chip;
public MotherBoard(Chip chip){
this.chip=chip;
}
public void init(){
System.out.println("MotherBoard is OK!");
chip.init();
}
}
芯片类
package mobile_phone2;
public class Chip {
private int size;
private String producer;
public Chip(int size,String producer){
this.size=size;
this.producer=producer;
}
public void init(){
System.out.println("chip is OK!");
}
}
第三者类(文本类)
package mobile_phone2;
public class Text {
public static void main(String[] args) {
Chip chip=new Chip(15,"China");
MotherBoard motherBoard=new MotherBoard(chip);
Phone phone=new Phone(motherBoard);
phone.init();
}
}
我们观察第三者类可以明显的发现,是先有了芯片类,给其定了参数,再有主板类,最后再有手机类的.
此时我们尝试去修改芯片类的内容,再给其加一个原材料
依赖其的类并没有发生错误,很明显降低耦合度的效果就已经达到了.
通过观察代码我们也可以发现一些特点,之前在传统的方式的代码中,依赖关系就好像是手机需要了某种主板,再去创建它,
同样的,在主板的创建中,也是需要了某种大小芯片,再去创建它,这就导致了,一但用户对底层的需求发生变化,那么也会影响导致上层发生改变,但是控制反转之后则不一样,这是就是第三方创建好了芯片类,你主板厂商不再去管其制作,就是去问第三方,有没有我要的芯片,给我来一打.同样的,手机类也是这样去和第三方交流.(这也凸显了一个优点:解耦,即不需要手机类再去主动创建主板类了)
控制权反转的
通过上面俩个图,比较下来我们就可以发现一个规律,传统的代码是由手机类来直接控制并且创建了其依赖的主板类,再由主板类控制创建了其依赖的芯片类,依次下去的.但是控制权反转之后我们发现不是了,是创建好了芯片类之后,依次往上为依赖其的类进行注入,就可以发现了,下级的创建是不再由上级直接控制,这样就是我们所说是IoC思想,即控制权反转思想.
1.解耦
2.使用更加高效
3.使用更加方便
我们已经认识了IoC,那么现在我们需要知道为什么Spring会被叫做包含众多工具方法的IoC容器呢,
首先包含众多工具方法的容器,这个不用多少,那么重点就是关注在IoC容器.
首先要知道Spring的核心:就是存入对象和取出对象
前面说了IoC是控制权反转,这么下来理解就很简单了.
DI--------Dependency injection,即 “依赖注入”.
我不知道你们都学过servlet没有,如果是学习过servlet而且使用过,我相信对dependency不会陌生,
在pom.xml下,需要我们操作最多的就是插入dependency,即引入依赖.
当然,没有学习过,也不需要去矛盾纠结.
前面我们已经介绍了IoC,我们知道了IoC是控制权反转,讲控制权交给别人,当其它用户需要使用对象时即可以从该容器中获取,那么这个获取的过程就是依赖注入,即引入依赖.
因此我们从广义上理解 依赖注入(DI) 和 控制权反转(IoC) 就是从不同的角度描述同一件事情.
但如果要细说的话,其实还是有区别的,我们前面也提到过,IoC其实是一种思想,但是DI则是这种思想的实现.
总的来说IoC和DI的大致含义和概念是不难理解的,重点是这种思路的实现(代码实现),其实不论在生活中还是学习过程中,都是这样,我们需要的是更多的练习才能达到更加深刻的理解,
我们主要讲的内容就是,理解IoC,理解DI,理解IoC和DI的联系.这就是本篇博客的全部内容了.