基本介紹
- 中文名:雙向注入
- 概念:Seam引入了bijection
- 用來:作為注入的廣義概括
- 功能:將上下文變數映射到組件實例變數
雙向注入,對比,概念,注入值,
雙向注入
Dependency injection(依賴注入)和 inversion of control(控制反轉)現在對大多數Java 開發者來說都是熟悉的概念了。依賴注入允許一個組件通過容器“注入”另一個組件到一個setter方法或者實例變數的方式,來獲得被“注入”組件的引用(reference)。我們之前看過的所有依賴注入的實現,注入發生在組件創建的時候,在此後實例的整個生命周期中不再改變。對無狀態組件,這么做是有道理的。從客戶端的角度來看,特定種類的無狀態組件的所有實例都是可以替換的。另一方面,Seam著重處理有狀態組件。此時傳統的依賴注入不再是非常有效了。Seam引入了 bijection(雙向注入)這個名詞,用來作為注入的廣義概括。和injection(單向注入)
對比
bijection是:
contextual(上下文相關的)- 雙向注入用來針對不同的上下文來組裝有狀態組件(在較大範圍的上下文中的組件,可以引用較小範圍上下文中的組件)
bidirectional(雙向的)- 被觸發後,值從上下文變數中注射到組件屬性中,也可以從組件屬性outjected(反向注入)回上下文,這樣被調用的組件可以只通過改寫自己的實例變數就同時操作了上下文變數的值
dynamic(動態的)- 因為上下文變數的值隨著時間不斷改變,而且因為Seam組件是有狀態的,雙向注入在每次組件被調用的時候都發生。
概念
基本上,通過設定實例變數是需要注入、反向注入、還是二者皆是,雙向注入讓你將上下文變數映射到組件實例變數。當然,我們使用註解來設定雙向注入。
@In 註解指明應該注入值,可能是注入實例變數:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { @In User user; ...}或者注入setter方法:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { User user; @In public void setUser(User user) { this.user=user; } ...}默認情況下,針對被注入的屬性或者實例變數名, Seam會對所有的上下文進行優先權搜尋。
注入值
你還可以注入表達式的值:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { @In("#{user.username}") String username; ...}(在下一章,有更多的關於組件生命周期和注射的內容。)
@Out 註解指定了某個屬性需要對外注入,可能是從實例變數:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { @Out User user; ...}或者從某個getter方法:
@Name("loginAction")@Stateless@Interceptors(SeamInterceptor.class)public class LoginAction implements Login { User user; @Out public User getUser() { return user; } ...}屬性可以既是被注入的,也可以對外注入:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { @In @Out User user; ...}或者:
@Name("loginAction")@Statelesspublic class LoginAction implements Login { User user; @In public void setUser(User user) { this.user=user; } @Out public User getUser() { return user; } ...}
如果你希望明確指定上下文變數名,可以這樣寫:@In("currentUser")!
如果沒有組件實例綁定到具名的上下文變數,你可能希望Seam創建一個,你可以指定 @In(create=true)。 如果值是可選的(可以為null),請指定 @In(required=false)。
對於某些組件,到處指定 @In(create=true) 是很繁瑣的。 你可以註解整個組件為 @AutoCreate,它就會在任何需要的時候自動創建,不需要明確的指定 create=true。