文章目錄
Java 上下文與依賴注入(JSR 299)[1]
轉載請保留作者資訊:
作者:88250
Blog:http:/blog.csdn.net/DL88250
MSN & Gmail & QQ:DL88250@gmail.com
摘要
本文從 JSR 299 規範入手,整理並翻譯了該規範中非常重要的概念,並結合一些短小的例子對 JSR 299 的使用進行了說明。文中略過了如何使用 XML 配置 bean,主要介紹使用標註(annotation)配置。
1. 綁定
1.1 定義新的綁定類型
@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Synchronous {}
@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Asynchronous {}
這裡定義了兩個綁定類型,@Synchronous 與 @Asynchronous,以後就可以使用它們定義 bean 了,這個定義步驟就是綁定。
對於型別安全解析演算法而言,綁定類型的成員值是非常重要的:
@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD})
public @interface PayBy {
PaymentMethod value();
}
1.2 綁定
這裡使用上述的綁定類型進行兩個 beans 的綁定:
@Synchronous
public class SynchronousPaymentProcessor
implements PaymentProcessor {
...
}
@Asynchronous
public class AsynchronousPaymentProcessor
implements PaymentProcessor {
...
}
這兩個 bean 都實現了 PaymentProcessor 這個 bean 類型,在注入點就可以根據需要進行注入了:
@Synchronous PaymentProcessor paymentProcessor;
@Asynchronous PaymentProcessor paymentProcessor;
一個 bean 可以定義多個綁定類型:
@Synchronous @Reliable
public class SynchronousReliablePaymentProcessor
implements PaymentProcessor {
...
}
1.3 預設綁定
預設綁定可以使用 @Current:
@Current
public class Order {}
等價於
public class Order {}
在注入時,
public class Order {
public Order(@Current OrderProcessor processor) { ... }
}
等價於
public class Order {
public Order(OrderProcessor processor) { ... }
}2. 範圍 2.1 內建的範圍2.1.1 @SessionScoped
該範圍被啟用於任意的 servlet.service() 方法,並跨越任意 filter.doFilter() 方法。Session 上下文將被所有同一 HTTP servlet session 內的 servlet requests 所共用,在 httpSession.invalidate() 方法調用時銷毀。
2.1.2 @RequestScoped
- 該範圍被啟用於任意的 servlet.service() 方法,並跨越任意 filter.doFilter() 方法。Request 上下文將在 servlet request 結束時被銷毀,即在 sevlet.service() 方法與所有 filter.doFilter() 方法返回後
- 該範圍被啟用於 Java EE web service 調用,並在該 web service 調用完成時銷毀
- 該範圍被啟用於任意的非同步觀察者方法通知時,並在該通知結束完成時銷毀
- 該範圍被啟用於任意的 EJB 遠程方法調用,並跨越任意 EJB 逾時方法以及對於任意 EJB 訊息驅動 bean 的訊息遞送。該上下文在遠程方法調用完成、逾時或訊息遞送完成時被銷毀
2.1.3 @ApplicationScoped
- 該範圍被啟用於任意的 servlet.service() 方法,並跨越任意 filter.doFilter() 方法
- 該範圍被啟用於 Java EE web service 調用
- 該範圍被啟用於任意的非同步觀察者方法通知時
- 該範圍被啟用於任意的 EJB 遠程方法調用,並跨越任意 EJB 逾時方法以及對於任意 EJB 訊息驅動 bean 的訊息遞送
Application 上下文在同一應用中的所有 servlets、非同步觀察者方法通知、web service 調用、EJB 遠程方法調用、EJB 逾時方法以及 EJB 訊息驅動 bean 的訊息遞送執行所共用,在應用反部署時被銷毀。該範圍可以看作是應用內的靜態範圍。
2.1.4 @ConversationScoped
後續文章分析
2.1.5 @Dependent
後續文章分析
範圍類型是可擴充的:
@ScopeType
@Inherited
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface BusinessProcessScoped {}
3. 部署類型
3.1 內建的部署類型
內建的部署類型:@Standard, @Production
部署類型是可擴充的:
@DeploymentType
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Australian {}
****
@Production
public class TaxPolicies {
@Produces @Australian
public TaxPolicy getAustralianTaxPolicy() { ... }
}
預設情況下,如果沒有顯示指定部署類型標註,bean 中的產生器方法或者欄位將繼承這個 bean 的部署類型。如果 bean 顯示聲明了部署類型,那麼由構型聲明的部署類型將被忽略。
4. 構型
在體繫結構設計中,構型是非常重要的一個概念。一個構型定義了一種 bean 角色,允許開發人員對這種 bean 統一地標識出公用的中繼資料。在 JSR 299 中,構型可以封裝下列概念的任意組合:
- 一個預設部署類型
- 一個預設範圍
- 對 bean 範圍的一個限制(restriction)
- 對一個 bean 實現或者是對一個類型的擴充的需求
- 一個攔截器綁定的集合
4.1 定義新的構型
@Stereotype
@RequestScoped
@Production
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}
標註了 @Action 的 bean 都將預設擁有 @RequestScoped 的範圍與 @Production 的部署類型,除非在 bean 上顯示標註了其他範圍與部署類型:
@Mock @ApplicationScoped @Action
public class MockLoginAction extends LoginAction { ... }
4.2 內建的構型
內建的構型有如下三種:
@Model
@Interceptor
@Decorator
後記
JSR 299 規範還處於草稿階段,從 EDR(Early Draft Review) 發布到現在改變很大:
- 規範名從 WebBeans -> Java Contexts and Dependency Inject -> Contexts and Dependency Injection for Java -> 目前最新的社區草稿 Contexts and Dependency Injection for Java EE
- 從對 Spring Bean & Seam Components 的明確支援 -> 使用 SPIs 方式支援
- 從對 SE 的支援 -> 沒有支援(WebBeans RI 倒是支援)
- 從提供 XML 配置 -> 不提供 XML 配置
- http://in.relation.to/Bloggers/NewDraftOfJSR299ForReviewByTheCommunity
不過,其核心思想:服務端組件狀態模型一點沒變,對 JSF EJB 的整合沒變。當然,目前改規範還不是很穩定,最終草稿可能在下個月發布,拭目以待。
術語中英對照
annotation: 標註
binding (type): 綁定(類型)
scope: 範圍
asynchronous: 非同步
observer: 觀察者
context: 上下文
deployment (type): 部署(類型)
stereotype: 構型
producer (method): 產生器(方法)
field: 欄位
injection point: 注入點
bean type: bean 類型