標籤:cdi aop singleton injection j2ee
這篇部落客要介紹CDI提供的不同bean的生命週期及在項目中如何使用它們。
介紹
當一個bean被CDI初始化時,這個bean通常會有自己的範圍。而賦予它的範圍通常就會決定了這個bean的整個生命週期。CDI提供的bean的生命週期:
| 範圍 |
使用 |
| ApplicationScoped |
當我們使用一個範圍被定義為應用程式範圍內的bean時那就意味著 整個bean會存在於應用程式的整個生命週期內。一旦這個bean被初始 化之後,每次用戶端請求建立該bean,應用程式都會保證請求的是同 一個執行個體。 |
| SessionScoped |
SessionScoped 主要用於web環境下應用的開發。當我們使用一個作 用域為session的CDI bean時,表示bean執行個體的生命週期取決於每個 Http Session。 |
| RequestScoped |
RequestScoped 主要用於web環境下應用的開發。當我們使用一個 範圍為session的CDI bean時,表示bean執行個體的生命週期取決於每 個Http 請求。
|
| ConversationScoped |
ConversationScoped主要用於web環境下應用的開發。如同其名一樣,ConversationScoped標誌用戶端同服務端的一次交流 。他們可能被 用於保持多個ajax請求或者不同頁面請求與服務端互動的狀態資訊。 |
注意:在Java EE7中介紹了一系列的CDI beans的範圍,如TransactionScoped,FlowScoped and ViewScoped.等等,更多資訊參考Java EE 7 CDI bean scopes。
CDI同時也提供了另外兩種pseudo-scopes:
| 範圍 |
使用 |
Singleton
|
如同其名一樣,Singleton bean標誌著單一實例,如果一個bean被用作Singleton意味著從始至終僅僅有一個執行個體存在。 |
Dependent
|
Dependent scope bean的範圍與其被注入的bean的範圍一樣。如當一個定義為Dependent的 bean被注入到一個會話bean中,那麼這個bean的範圍和生命週期同這個會話bean一樣,當會話 結束此bean的生命週期也就截止了。 |
代理
當一個被CDI容器管理的bean被注入到其他bean中時,CDI容器並不是注入的bean執行個體,而是注入的一個代理類。通常這個代理類會將用戶端的相應請求再轉寄給相應的bean去處理。
想想SessionScoped bean,如果不同的會話請求一個SessionScoped 會話執行個體,這些請求都會被交給同一個代理處理。當這些請求訪問這些被代理的對象時,代理對象知道如何找到相應的對象執行個體並為相應的會話提供這卻的服務。
注意:單例的 pseduo-scope與這種代理模式正好相對應。當一個用戶端請求一個單例的bean時,CDI容器會將這個bean的執行個體注入到相應的bean中而不再是一個代理。
序列話
一些被CDI容器管理的bean可以保持很長時間的生命週期,如SessionScoped、ConversationScoped,但是他們必須實現序列化介面。這是由於容器要釋放一些資源,而這些資源往往需要連同bean的類資訊持久化到物理磁碟上,等到程式再次需要的時候能夠保證容器再次將這些bean的狀態從物理磁碟中恢複出來。
Singleton pseudo-scoped
我們知道當我們使用Singlescoped 時,用戶端會得到該對象執行個體的真正引用。因此當用戶端請求的是序列化的,就必須保證這個執行個體是單例的。我們而保證這個單例的bean是一個正真的單例的方法如下:
1.正如java序列話標準聲明的那樣,這個單例要實現writeReplace()和readResolve()方法。
2.維護單例的引用對象的瞬時狀態,當容器反序序列化該對像時,容器要保證重新注入該對象的引用。
Dependent pseudo-scope
如果沒有特別聲明的話,Dependent是CDI預設的範圍。Dependent意味著注入的bean與被注入的bean有相同的範圍。用戶端不會共用執行個體,每個用戶端拿到的將會是一個新的對象執行個體。
view scope
update:在java EE7中增加了viewscoped,詳細資料請參考Java EE 7 CDI bean scopes和Java EE CDI ViewScoped example.
如果你熟悉JSF bean的範圍,您可能想知道哪個viewscoped bean符合這個模型。CDI不提供任何viewscoped但提供conversationscoped代替。
conversationscoped與我們實現相同的功能,通常需要從一個viewscoped的JSF bean(bean之間保持狀態的Ajax請求),更有可能保持不同的頁面請求的相同的對話或狀態。
註:請記住,如果使用者離開目前的交談而沒有結束這樣的對話機會,託管bean將保持有效,直到它逾時。所以如果你有一個真正的問題這些bean一直有效到逾時,如果真需要像JSF viewscoped bean的bean,你應該參考下面的實現以代替:
.Apache deltaspike(前縫面)
.ViewAccessScope beans from MyFaces CODI
Java EE CDI bean生命週期介紹