1. IOC 控制反转
IOC : inversion of control 控制反转 ----实例化的一个过程 实例化的主动权交给Spring ,以配置的形式来进行,将实例化的对象放入Spring容器中。即, 通过Spring容器管理Java类的对象,而不是在Java类中new一个对象。
好莱坞法则:“别找我们,我们找你” 为什么叫控制反转?顾名思义,将寻找(实例化)对象的控制权转交给容器,而不是自己控制这个对象。
没理解?别着急!往下看。 提前告诉你: 别找我们 ,别傻乎乎地在自己的类里面引入另一个类,耦合度高,牵一发动全身~ 我们找你,你都不找我了,怎么用我们啊,只能我们自己上门了。这个上门可不是在你那打地基盖房子,而是我们携家带口揣着户口本房产证上门,就是说,该有的我们都有,我们是对象,不用new, 给你注入你用就行。
2. DI 依赖注入
DI:Dependency Injection 目的:保持松散耦合
2.1 常规方式
骑士为了展现自己的冒险精神,自己new 了一个Quest对象,然后对此对象进行操作。骑士打败了坏蛋Bully,他觉得自己升级了,“老子天下第一”,我要去杀死恶龙。然而骑士发现,我TM去哪找恶龙啊?好,我千辛万苦在苦逼程序员手动引入的前提下找到了恶龙类,new 一个外部的恶龙类才能杀龙,好麻烦啊。
初级骑士
public class Knight {
private Quest quest;
public Knight() {
this.quest = new Quest();
}
public void embark() {
System.out.println("骑士将要做的事:");
quest.killBully();
}
}
冒险类1—坏蛋类
public class Quest1 {
public String killBully() {
return "kill Bully";
}
}
升级后的骑士
好,作为骑士我现在可以屠龙了。感谢帮我引入恶龙类的新时代码农!码农啊,你是否产生了这样一个疑问:直接在Quest1—坏蛋类里加一个方法,让坏蛋骑着恶龙,我作为骑士,再引入一个屠龙的方法就行啊。码农再想,不对啊,这不就破坏了Java的封装性了吗?两个实体类合成一个,你是想直接打BOSS吗,不行!万一世界上还有什么青龙、白龙呢?
public class Knight {
private Quest1 quest1;
private Quest2 quest2;
public Knight() {
this.quest1 = new Quest1();
this.quest2 = new Quest2();
}
public void embark() {
System.out.println("骑士将要做的事:");
quest1.killBully();
quest2.killDragon();
}
}
冒险类2----恶龙类
public class Quest2 {
public String killDragon() {
return "kill dragon";
}
}
2.2 头秃的骑士
骑士觉得老是靠程序员帮自己做事,面子挂不住。于是,有一天,骑士找了一个中介,也就是Spring容器,中介可以通过XML配置的形式,向骑士注入一系列信息。这下码农着急了,你这不开挂吗?码农想学习到这种技术,然后把骑士的生意抢回来! 那我就教你 “注入” !! 先给你灌输一个词汇:接口
升级后的探险
public interface QuestPro {
public void embark();
}
坏蛋被探险
public class BullyImpl implements QuestPro {
@Override
public void embark() {
System.out.println("kill bully");
}
}
恶龙被探险
public class DragonImpl implements QuestPro {
@Override
public void embark() {
System.out.println("kill dragon");
}
}
最强骑士
public class KnightPro {
private QuestPro questPro;
public KnightPro(QuestPro questPro) {
this.questPro = questPro;
}
public void quest() {
questPro.embark();
}
}
骑士说!
加了接口就是注入了吗?并不是!码农啊,你想一想,是不是QuestPro被注入骑士类了,那谁来实例化这个QuestPro呢? 答案就是中介!通过XML配置给骑士注入一个对象,而不需要骑士自己去new。 骑士:确实不能自己new, 即使是实现了接口,那我自己new的时候,还需要new 两个对象!
QuestPro q1 = new BullyImpl();
QuestPro q2 = new DragonImpl();
这和不用接口什么区别!还是得靠中介注入啊。直接注入对象,你注入啥我就用啥,来者不拒。
public KnightPro(QuestPro questPro) {
this.questPro = questPro;
}
3. 总结
码农明白了!如果骑士还想继续升级,无论是怪兽还是奥特曼,只要实现了QuestPro接口;中介注入给骑士一个对象,那骑士就可以出手了,而且自己内部还不用变动。 扛着长枪短炮的去冒险太麻烦了,轻装上阵才最强!
程序的整个思想是控制反转,具体实现采用依赖注入! 专业术语表示: 控制反转:实例化的主动权交给Spring ,以配置的形式来进行,将实例化的对象放入Spring容器中。 依赖注入: 什么是依赖?冒险类依赖于骑士类,没有骑士哪来的冒险! 什么是注入?就是不用自己实例化对象,用到的对象都是外界传入的。
|