控制反轉(IOC):java
由框架或其餘某些東西來控制須要調用的事件處理器或其餘東西,而不是由業務邏輯決定。spring
舉例:spring中的bean,咱們在spring項目中配置了datasource後,不須要關注如何調用它,調用它這個工做交給spring,咱們只須要關注咱們的真正業務。數據庫
這樣主控被反轉了。控制權從業務邏輯中轉移到其餘地方。數據庫操做典型的例子:打開和關閉鏈接。框架
IoC的不一樣實現:1.工廠模式 2.服務定位器模式 3.依賴注入(DI)ide
IoC會確保一個可重用的依賴項會被配置成單例。.net
依賴注入(DI):調試
依賴注入是IoC的一種特定形態,是指尋找依賴項的過程不在當前執行代碼的直接控制之下。固然咱們也能夠本身寫代碼實現依賴注入。code
注:把依賴項注入對象的方法有不少種,可使用專門的DI框架,也能夠顯示的建立對象實例(依賴項)並把它們傳入對象中也能夠和框架注入達到一樣效果。對象
DI的幾個明顯特色:鬆耦合,易測性,內聚性(專一業務),可重用,代碼更少。接口
發展:
JAVA DI標準化方式JSR-330進行統一的規範依賴注入,2009年 JSR-299在300基礎上規範企業應用提供標準化配置。實現是 javax.inject。
瞭解依賴注入機制的內部工做原理能夠解決不少常見的問題:
1.依賴項配置錯誤,2.依賴項詭異的超出做用域,3.依賴項在不應共享時被共享以及分佈調試離奇跌機。
javax.inject包含一個 Provider<T> 接口 和 5個註解類型 @Inject @Qualifier @Named @Scope @Singleton
詳解:
@Inject 範圍: 1.構造器,2.方法 ,3.屬性
在構造器上使用時,構造器的參數會在運行時有配置好的IoC容器提供。在不含參數的構造器上使用Inject也合法。
注:JRE沒法決定構造器注入的優先級,因此規範中規定類中只能有一個構造器帶@Inject註解。
在方法上使用時,不能聲明方法爲抽象的。也不能聲明其自身的類型參數。
@ Qualifier
用於區別兩個相同類型的對象。JSR330要求全部IOC容器都必須提供一個默認的@Qualifier註解。@Named--用來給兩個相同類型的對象設置不一樣的別名
@Scope
用於定義注入器(IOC容器)對注入對象的重用方式。
若是沒有聲明該註解,IOC應該建立注入對象而且僅使用該對象一次。
@ Singleton
在須要注入一個不會改變的對象時就要用 @ Singleton
Provider<T>
若是要對由DI框架注入代碼中的對象有更多控制權,能夠要求DI框架將Provider<T>接口實現注入對象。這樣,
1.能夠獲取該對象的多個實例
2.能夠延遲獲取該對象
3.能夠打破循環依賴
4.能夠定義做用域
該接口僅有一個T get()方法,返回一個注入好的注入對象T。
Class Mur{ @Inject Mur (Provider<Message> messageProvider){ Message m1=messageProvider.get(); if(someGlobalCondition){ Message copyMsg1=messageProvider.get(); } ..... } }