為什么要用IOC?
第一:對象的實例化不是一件簡單的事情,比如對象的關系比較復雜,依賴關系往往需要程序員去維護,這是一件非常頭疼的事。
第二:解耦,由容器去維護具體的對象
第三:托管了類的產生過程,比如我們需要在類的產生過程中做一些處理,最直接的例子就是代理,如果有容器程序可以把這部分過程交給容器,應用程序則無需去關心類是如何完成代理的
控制反轉(Inverse of Control)
控制反轉即IoC(Incersion of Control),從字面上理解就是控制反轉,將對在自身對象中的一個內置對象的控制權反轉。所謂的反轉,即把內置對象的控制權反轉給一個容器,而應用程序只需要提供對象的類型即可。
這是一種解耦的設計思想,並不是什么具體的技術。基本思想是:借助於“第三方”實現具有依賴關系的對象之間的解耦。實現IOC的技術手段:DI(依賴注入)和 DL(依賴查找),Spring中的核心機制就是DI(依賴注入)。通俗來說就是ServiceImpl類中,有Dao 對象,那就是ServiceImpl依賴了Dao。
這里引用3張圖就非常明顯表示IOC容器的作用:解耦



依賴注入(Depedency Injection)
意思是自身對象中的內置對象是通過注入的方式進行創建。依賴注入有兩種實現方式:Setter方式(傳值方式)和構造器方式(引用方式)。
容器全權負責組件的裝配,它會把符合依賴關系的對象通過屬性(JavaBean中的setter)或者是構造子傳遞給需要的對象。
相對於IoC而言,依賴注入(DI)更加准確地描述了IoC的設計理念。所謂依賴注入,即組件之間的依賴關系由容器在應用系統運行期來決定,也就是由容器動態地將某種依賴關系的目標對象實例注入到應用系統中的各個關聯的組件之中。
依賴查找(Dependency Lookup)
谷歌中還有個資料表明:依賴查找也有兩種類型:依賴拖拽(DP)和上下文化依賴查找(CDL)。
http://what-when-how.com/Tutorial/SpringFramework3/SpringFramework300052.html
依賴拖拽 (Dependency Pull)
依賴拖拽:注入的對象如何與組件發生聯系,這個過程就是通過依賴拖拽實現 。(較少有使用)
依賴拖拽示例代碼:
1 public class DependencyPullDemo { 2 public static void main(String[] args) { 3 BeanFactory beanFactory = getBeanFactory(); 4 MessageService messageService = (MessageService) beanFactory.getBean("service"); 5 messageService.execute(); 6 } 7 private static BeanFactory getBeanFactory() { 8 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); 9 BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(beanFactory); 10 reader.loadBeanDefinitions(new ClassPathResource("/META-INF/spring/ioc-pull-context.properties")); 11 return beanFactory; 12 } 13 }
而通常對注入對象的配置可以通過一個 xml 文件完成。
依賴拖拽這種方式對對象進行集中管理。
上下文依賴查找(Contextualized Dependency Lookup)
在某些方面跟依賴拖拽類似,但是上下文依賴查找中,查找的過程是在容器管理的資源中進行的,而不是從集中注冊表中,並且通常是作用在某些設置點上。
1 public class ContextualizedDependencyLookupDemo 2 { 3 private static Set<ManagedComponent> components = new HashSet<ManagedComponent>(); 4 private static class MessageServiceComponent implements ManagedComponent{ 5 private MessageService messageService; 6 public void lookup(BeanFactory beanFactory) { 7 this.messageService = (MessageService) beanFactory.getBean("service"); 8 } 9 } 10 }
使用依賴拖拽與上下文依賴查找本質的區別是:上下文依賴查找是在業務組件代碼中進行的,而依賴拖拽是從一個集中的注冊處,特定的地點執行。
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.
對於Java開發人員來說,依賴拖拽是最常見的IoC類型。在依賴拖拽中,根據需要從注冊表中提取依賴項。
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組件)。
這里再加上一個依賴拖拽的Demo:
總結:
依賴查找(Dependency Lookup):容器中的受控對象通過容器的API來查找自己所依賴的資源和協作對象。這種方式雖然降低了對象間的依賴,但是同時也使用到了容器的API,造成了我們無法在容器外使用和測試對象。 依賴查找是一種更加傳統的IoC實現方式。
依賴注入(Dependency Injection):依賴注入就是將服務注入到使用它的地方。對象只提供普通的方法讓容器去決定依賴關系,容器全權負責組件的裝配,它會把符合依賴關系的對象通過屬性(JavaBean中的setter)或者是構造子傳遞給需要的對象。
相對於IoC而言,依賴注入(DI)更加准確地描述了IoC的設計理念。所謂依賴注入,即組件之間的依賴關系由容器在應用系統運行期來決定,
也就是由容器動態地將某種依賴關系的目標對象實例注入到應用系統中的各個關聯的組件之中。
這就是我對IOC、DI和DL的理解。本質就是把類的內置對象的控制權交給了容器。
參考文章:
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
網上發現接近40%的文章寫到IOC就是DI,在這明確說明這是錯誤的說法。
本人才疏學淺,以上純屬個人理解,如有不對,還望批評指正。