依賴(lài)注入(dependency inject)
依賴(lài)是開(kāi)發(fā)中不可缺少的場(chǎng)景,每一個(gè)業(yè)務(wù)需求都需要多個(gè)類(lèi)都實(shí)體相互依賴(lài)完成,但是對(duì)象之間的依賴(lài)卻給開(kāi)發(fā)帶來(lái)了很多不便,因此提出了注入的概念。
舉個(gè)例子:
public class?Soldier {
public void?shot(){
System.out.println("soldier shot!");
}
}
Knight有一個(gè)方法attack,要完成這個(gè)舉動(dòng)必須要soldier來(lái)進(jìn)行,也就是Knight依賴(lài)Soldier,所以這里兩個(gè)類(lèi)就緊耦合在一起。
所以Knight的attack就受到了Soldier的限制了,那依賴(lài)注入怎么解決?
1.把Soldier定義為一個(gè)接口
2.通過(guò)Knight的構(gòu)造器注入Soldier的具體對(duì)象
3.對(duì)于Knight而言,無(wú)需關(guān)注Soldier具體是實(shí)現(xiàn)類(lèi),只需要在attack時(shí)調(diào)用soldier進(jìn)行shot即可
public class?Knight {
private?Soldier?soldier;
public?Knight(Soldier soldier) {
this.soldier?= soldier;
}
public void?attack(){
soldier.shot();
}
}
public interface?Soldier {
public void?shot();
}
public class?Navy?implements?Soldier {
@Override
public void?shot() {
System.out.println("navy attack!");
}
}
public class?AirForce?implements?Soldier {
@Override
public void?shot() {
System.out.println("AirForce is attacking!");
}
}
public class?Knight {
private?Soldier?soldier;
public?Knight() {
soldier?=?new?Soldier();
}
public void?attack(){
soldier.shot();
}
}
依賴(lài)注入往往和控制反轉(zhuǎn)(Inversion of Control)說(shuō)到一起,控制反轉(zhuǎn)指對(duì)象的控制權(quán)、生命周期等行為不再由客戶(hù)端(調(diào)用方)來(lái)控制,而是由IoC容器來(lái)控制,調(diào)用方不再需要關(guān)心他要調(diào)用的對(duì)象如何產(chǎn)生,只要告訴容器,我要用某個(gè)對(duì)象了,由容器來(lái)提供。
傳統(tǒng)的編程方式,在對(duì)象需要另一個(gè)對(duì)象時(shí),都是主動(dòng)來(lái)創(chuàng)建對(duì)象,控制對(duì)象都行為,因此這種通過(guò)容器來(lái)提供對(duì)象都創(chuàng)建和銷(xiāo)毀都方式,形象的成為控制反轉(zhuǎn)。
Spring框架通過(guò)Ioc這種設(shè)計(jì)思想,將所有的類(lèi)都注冊(cè)到容器中,告訴容器:
1.A是什么類(lèi)
2.A需要哪些類(lèi)(依賴(lài))
有了這兩個(gè)信息,在程序運(yùn)行的時(shí)候,容器就會(huì)在適當(dāng)?shù)臅r(shí)候把依賴(lài)的類(lèi)注入到A中,對(duì)A來(lái)說(shuō),以前是他控制這些依賴(lài)類(lèi),現(xiàn)在就是統(tǒng)一由Spring容器來(lái)提供,這種控制的行為就被反轉(zhuǎn)了。
依賴(lài)注入是基于java的反射機(jī)制實(shí)現(xiàn)的,java提供了反射機(jī)制,在程序運(yùn)行中,就可以通過(guò)反射得到一個(gè)類(lèi)的全部屬性和方法,并且可以調(diào)用,Spring就可以通過(guò)xml或者注解等方式,得到交給容器控制的所有類(lèi)的依賴(lài)關(guān)系,在程序運(yùn)行過(guò)程中進(jìn)行創(chuàng)建,并且可以執(zhí)行這些類(lèi)的行為。