2010-08-21 107 views
6

我們如何在不使用容器的情況下手動注入對象。我通過反思做了類似的事情,如下所示。如何手動實現依賴注入?

Class actionClass = Class.forName("SampleClass"); 
Object actionObject = actionClass.newInstance(); 
Method reqMethod = actionClass.getMethod("setRequest", HttpServletRequest.class); 
reqMethod.invoke(actionObject,request); 

這是DI的正確方法嗎?

我的目的是通過請求對象不同控制器類動態地從一個調度員過濾器,在那裏我們得到請求和響應對象。 我很擔心反射的表現。是否有替代做DI的替代品?

回答

0

依賴注入意味着你得到正確的初始化引用出現「魔術」。

與您通話請求對象了setRequest()方法,但DI經常也允許設置字段而不調用方法。

Guice並不像這樣需要一個容器,而是使用主要方法啓動的類加載器魔術。這對你有用嗎?

+0

我喜歡「魔術」這個詞。初始化如何發生。它是如何在Spring或類似的DI容器中完成的。 – 2010-08-21 10:08:15

+1

這個想法是將注入的類和注入發生的類從初始化中移走,所以他們不知道它是如何發生的。然後將注入代碼移到哪裏,取決於實現,而_you_本質上不需要知道。最後使用了反射,但這就像說Hibernate最終使用JDBC一樣。 – 2010-08-21 10:29:30

+0

我的意圖是將請求對象從調度程序過濾器動態地傳遞給不同的控制器類,在那裏我們獲取請求和響應對象。 – 2010-08-21 11:07:34

5

依賴注入無非是提供一類具有它的依賴,而不是把它找到他們自己(通過單身/查找等)等等。所以你可以這樣簡單代碼:

DatabaseConnection dc = new DatabaseConnection(); 
MyDAO dao = new MyDAO(dc); 

(僞代碼)。這裏MyDAO被注入一個數據庫連接。如果該數據庫連接實現了一個接口,則可以在測試過程中輕鬆地將其剔除。

2

那麼,當你設置一個對象爲使用setter方法或通過構造另一個對象,也就是依賴注入。依賴注入只意味着在對象中創建關係(依賴關係)。

像你這樣使用反射只是它的另一種形式。

1

爲什麼要使用反射?爲什麼不乾脆:

SampleClass action = new SampleClass(); 
action.setRequest(request); 

,做同樣的事情,但更具有可讀性,使編譯器檢查的類型和方法確實存在,爲您提供Javadoc文檔調用該方法,使您的IDE協助重構,...

它仍然是依賴注入,因爲動作不去找它的請求,但在初始化過程中接收請求。

編輯:Thorbjørn要求我說明如何使用該動作。它本身會被注入(使用setter)到任何使用該動作的組件中。該組件將使用注入的操作對象。

SampleClass action = new SampleClass(); 
action.setRequest(request); 
Servlet servlet = new ActionBasedServlet(); 
servlet.setAction(action); 

如果servlet旨在活得比action,即它應該使用它需要一個新的Action每一次,一個可以代替setter方法注入的ActionFactoryservlet

在這個具體的例子,我會質疑行爲是否真的需要保持一個請求作爲其狀態的一部分,也可以是不可變的,只是作用於由Servlet作爲方法參數傳遞的請求。在這種情況下,引導時初始化會做:

SampleClass action = new SampleClass(); 
Servlet servlet = new ActionBasedServlet(); 
servlet.setAction(action); 

ActionBasedServlet將定義

public void serve(Request req, Response resp) { 
    foo(); 
    action.act(req, resp); 
    bar(); 
} 
+0

'new'關鍵字從當前類到新類都提供了非常強大的綁定。依賴注入_將兩者之間的這種強有力的約束聯繫起來。 – 2010-08-21 10:31:43

+3

依賴注入將組件從其依賴關係中分離出來。這並不意味着代碼的另一部分不能知道組件及其依賴關係。在我的例子中,SampleClass沒有耦合到特定的請求。 – meriton 2010-08-21 10:38:00

+0

在我的情況下,類名是動態的。爲所有類創建一個通用的DI。即爲什麼我使用反射。感謝您的回答。 – 2010-08-21 11:03:26

0

Spring框架是最流行的DI實現之一。它也是開源的。 有關如何執行此操作的示例,可以查看org.springframeowrk.beans.BeanUtils類,特別是方法copyProperties(全部4個)。 欲瞭解更多信息,你還可以看到不同策略org.springframework.beans.factory.BeanFactory的類層次結構。