為什么要用IOC?
第一:對(duì)象的實(shí)例化不是一件簡(jiǎn)單的事情,比如對(duì)象的關(guān)系比較復(fù)雜,依賴關(guān)系往往需要程序員去維護(hù),這是一件非常頭疼的事。?
第二:解耦,由容器去維護(hù)具體的對(duì)象?
第三:托管了類的產(chǎn)生過程,比如我們需要在類的產(chǎn)生過程中做一些處理,最直接的例子就是代理,如果有容器程序可以把這部分過程交給容器,應(yīng)用程序則無(wú)需去關(guān)心類是如何完成代理的
控制反轉(zhuǎn)(Inverse of Control)
控制反轉(zhuǎn)即IoC(Incersion of Control),從字面上理解就是控制反轉(zhuǎn),將對(duì)在自身對(duì)象中的一個(gè)內(nèi)置對(duì)象的控制權(quán)反轉(zhuǎn)。所謂的反轉(zhuǎn),即把內(nèi)置對(duì)象的控制權(quán)反轉(zhuǎn)給一個(gè)容器,而應(yīng)用程序只需要提供對(duì)象的類型即可。
這是一種解耦的設(shè)計(jì)思想,并不是什么具體的技術(shù)。基本思想是:借助于“第三方”實(shí)現(xiàn)具有依賴關(guān)系的對(duì)象之間的解耦。實(shí)現(xiàn)IOC的技術(shù)手段:DI(依賴注入)和 DL(依賴查找),Spring中的核心機(jī)制就是DI(依賴注入)。通俗來(lái)說就是ServiceImpl類中,有Dao 對(duì)象,那就是ServiceImpl依賴了Dao。
這里引用3張圖就非常明顯表示IOC容器的作用:解耦
依賴注入(Depedency Injection)
意思是自身對(duì)象中的內(nèi)置對(duì)象是通過注入的方式進(jìn)行創(chuàng)建。依賴注入有兩種實(shí)現(xiàn)方式:Setter方式(傳值方式)和構(gòu)造器方式(引用方式)。
容器全權(quán)負(fù)責(zé)組件的裝配,它會(huì)把符合依賴關(guān)系的對(duì)象通過屬性(JavaBean中的setter)或者是構(gòu)造子傳遞給需要的對(duì)象。
相對(duì)于IoC而言,依賴注入(DI)更加準(zhǔn)確地描述了IoC的設(shè)計(jì)理念。所謂依賴注入,即組件之間的依賴關(guān)系由容器在應(yīng)用系統(tǒng)運(yùn)行期來(lái)決定,也就是由容器動(dòng)態(tài)地將某種依賴關(guān)系的目標(biāo)對(duì)象實(shí)例注入到應(yīng)用系統(tǒng)中的各個(gè)關(guān)聯(lián)的組件之中。
依賴查找(Dependency Lookup)
谷歌中還有個(gè)資料表明:依賴查找也有兩種類型:依賴拖拽(DP)和上下文化依賴查找(CDL)。
http://what-when-how.com/Tutorial/SpringFramework3/SpringFramework300052.html
依賴拖拽 (Dependency Pull)
依賴拖拽:注入的對(duì)象如何與組件發(fā)生聯(lián)系,這個(gè)過程就是通過依賴拖拽實(shí)現(xiàn)?。(較少有使用)
依賴拖拽示例代碼:
public class DependencyPullDemo {
? ? public static void main(String[] args) {
? ? ? ? BeanFactory beanFactory = getBeanFactory();
? ? ? ? MessageService messageService = (MessageService) beanFactory.getBean("service");
? ? ? ? messageService.execute();
? ? }
? ? private static BeanFactory getBeanFactory() {
? ? ? ? DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
? ? ? ? BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(beanFactory);
? ? ? ? reader.loadBeanDefinitions(new ClassPathResource("/META-INF/spring/ioc-pull-context.properties"));
? ? ? ? return beanFactory;
? ? }
}
而通常對(duì)注入對(duì)象的配置可以通過一個(gè)?xml?文件完成。
依賴拖拽這種方式對(duì)對(duì)象進(jìn)行集中管理。
上下文依賴查找(Contextualized Dependency Lookup)
在某些方面跟依賴拖拽類似,但是上下文依賴查找中,查找的過程是在容器管理的資源中進(jìn)行的,而不是從集中注冊(cè)表中,并且通常是作用在某些設(shè)置點(diǎn)上。
public class ContextualizedDependencyLookupDemo
{?
? ? private static Set<ManagedComponent> components = new HashSet<ManagedComponent>(); ?
? ? private static class MessageServiceComponent implements ManagedComponent{?
? ? ? ? private MessageService messageService; ?
? ? ? ? public void lookup(BeanFactory beanFactory) {?
? ? ? ? ? ? this.messageService = (MessageService) beanFactory.getBean("service");?
? ? ? ? }?
? ? }
}
使用依賴拖拽與上下文依賴查找本質(zhì)的區(qū)別是:上下文依賴查找是在業(yè)務(wù)組件代碼中進(jìn)行的,而依賴拖拽是從一個(gè)集中的注冊(cè)處,特定的地點(diǎn)執(zhí)行。
Dependency Pull To a Java developer, Dependency Pull is the most familiar type of IoC.?In Dependency Pull,dependencies are pulled from a registry as required.
對(duì)于Java開發(fā)人員來(lái)說,依賴拖拽是最常見的IoC類型。在依賴拖拽中,根據(jù)需要從注冊(cè)表中提取依賴項(xiàng)。
?Anyone who has ever written code to access an EJB(2.1 or prior versions) has used Dependency Pull (i.e., via the JNDI API to look up an EJB component).
任何編寫過訪問EJB(2.1或更早版本)的代碼的人都使用過依賴拖拽(即,通過JNDI API查找EJB組件)。
這里再加上一個(gè)依賴拖拽的Demo:
總結(jié):
依賴查找(Dependency Lookup):容器中的受控對(duì)象通過容器的API來(lái)查找自己所依賴的資源和協(xié)作對(duì)象。這種方式雖然降低了對(duì)象間的依賴,但是同時(shí)也使用到了容器的API,造成了我們無(wú)法在容器外使用和測(cè)試對(duì)象。 依賴查找是一種更加傳統(tǒng)的IoC實(shí)現(xiàn)方式。
依賴注入(Dependency Injection):依賴注入就是將服務(wù)注入到使用它的地方。對(duì)象只提供普通的方法讓容器去決定依賴關(guān)系,容器全權(quán)負(fù)責(zé)組件的裝配,它會(huì)把符合依賴關(guān)系的對(duì)象通過屬性(JavaBean中的setter)或者是構(gòu)造子傳遞給需要的對(duì)象。
相對(duì)于IoC而言,依賴注入(DI)更加準(zhǔn)確地描述了IoC的設(shè)計(jì)理念。所謂依賴注入,即組件之間的依賴關(guān)系由容器在應(yīng)用系統(tǒng)運(yùn)行期來(lái)決定,
也就是由容器動(dòng)態(tài)地將某種依賴關(guān)系的目標(biāo)對(duì)象實(shí)例注入到應(yīng)用系統(tǒng)中的各個(gè)關(guān)聯(lián)的組件之中。
這就是我對(duì)IOC、DI和DL的理解。本質(zhì)就是把類的內(nèi)置對(duì)象的控制權(quán)交給了容器。
參考文章:
IOC:https://blog.csdn.net/java_lyvee/article/details/83514583
依賴拖拽:http://www.voidcn.com/article/p-upbcskxv-bmm.html;https://www.xuebuyuan.com/zh-hant/1903214.html
依賴查找JNDI例子:https://blog.csdn.net/beijiguangyong/article/details/43347351
依賴注入:https://blog.csdn.net/Baple/article/details/53667767
圖片引用:https://www.cnblogs.com/Nouno/p/5706103.html
網(wǎng)上發(fā)現(xiàn)接近40%的文章寫到IOC就是DI,在這明確說明這是錯(cuò)誤的說法。
本人才疏學(xué)淺,以上純屬個(gè)人理解,如有不對(duì),還望批評(píng)指正。