EJB 3.1五大模式改進(jìn)令Java EE 6更好用
原創(chuàng)【51CTO精選譯文】EJB(Enterprise JavaBeans)是使用Java EE開(kāi)發(fā)和部署業(yè)務(wù)應(yīng)用系統(tǒng)的服務(wù)端組件架構(gòu),使用EJB編寫的應(yīng)用系統(tǒng)是可擴(kuò)展的、事務(wù)型和安全的。EJB 3.0是Java EE 5平臺(tái)的一部分,相對(duì)前面的版本,它更加易于使用,它的***版本 — JSR318:EJB 3.1 — 隨Java EE 6發(fā)布,進(jìn)一步簡(jiǎn)化了使用,并提供了許多反應(yīng)常見(jiàn)使用模式的改進(jìn),如:
1、無(wú)接口視圖:允許你指定一個(gè)企業(yè)Bean,只使用Bean類,不用編寫?yīng)毩⒌臉I(yè)務(wù)接口。
2、單元素集合:讓你在一個(gè)企業(yè)Bean組件的多個(gè)實(shí)例間輕松地共享狀態(tài),或是在一個(gè)應(yīng)用程序的多個(gè)企業(yè)Bean組件之間共享狀態(tài)。
3、異步會(huì)話Bean調(diào)用:通過(guò)指定一個(gè)注解,讓你可以異步調(diào)用會(huì)話狀態(tài)方法。
4、簡(jiǎn)化打包:消除了企業(yè)Bean類必須打包到ejb-jar文件的限制,現(xiàn)在你可以直接將EJB類放到WAR文件中。
5、輕量級(jí)EJB:它是EJB 3.1的子集,包括大量的Java EE profiles。
無(wú)接口視圖
#t#EJB 3.0本地客戶端視圖是基于普通舊式Java接口(POJI)調(diào)用本地業(yè)務(wù)接口的,本地接口定義了暴露給客戶端的業(yè)務(wù)方法,并是在Bean類上實(shí)現(xiàn)的,這種獨(dú)立的接口有時(shí)會(huì)帶來(lái)不必要的麻煩,并且價(jià)值也不大,相同模塊內(nèi)的來(lái)自客戶端的本地訪問(wèn)細(xì)粒度組件尤其如此。
EJB 3.1通過(guò)讓本地業(yè)務(wù)接口成為可選組件簡(jiǎn)化了這個(gè)方法,沒(méi)有本地業(yè)務(wù)接口的Bean暴露的是無(wú)接口視圖,現(xiàn)在你不用編寫?yīng)毩⒌臉I(yè)務(wù)接口就可以獲得相同的企業(yè)Bean功能。
無(wú)接口視圖與EJB 3.0中的本地視圖具有相同的行為,例如,它支持如通過(guò)按引用調(diào)用語(yǔ)義、事務(wù)和安全傳播等特性,但無(wú)接口視圖不需要單獨(dú)的接口,即Bean類所有的公共方法自動(dòng)暴露給調(diào)用者。默認(rèn)情況下,任何有空implements子句,且沒(méi)有定義任何其它本地或遠(yuǎn)程客戶端視圖的會(huì)話Bean,暴露的是一個(gè)無(wú)接口視圖。下面的會(huì)話Bean暴露了一個(gè)無(wú)接口視圖:
- @Stateless
- public class HelloBean {
- public String sayHello() {
- String message = propertiesBean.getProperty("hello.message");
- return message;
- }
- }
使用本地視圖時(shí),無(wú)接口視圖的客戶端總是獲得一個(gè)EJB引用 — 通過(guò)注入或JNDI查找,唯一的不同之處是EJB引用的Java類型是Bean類類型,而不是本地接口的類型,如下面的Bean客戶端:
- @EJB
- private HelloBean helloBean;
- ...
- String msg = helloBean.sayHello();
注意,雖然這里沒(méi)有接口,客戶端不能使用new()明確地實(shí)例化Bean類,那是因?yàn)樗蠦ean調(diào)用都是通過(guò)一個(gè)特殊的EJB引用,或由容器提供的代理實(shí)現(xiàn)的,這樣就允許容器提供其它的Bean服務(wù),如池、容器管理的事務(wù),并發(fā)管理等。
#p#
單元素集合
單元素集合Bean也被稱為單元素集合,它是一種新的會(huì)話Bean,它保證在一個(gè)特定的Java虛擬機(jī)(JVM)應(yīng)用程序中只被實(shí)例化一次。使用單元素集合,你可以在一個(gè)企業(yè)Bean組件的多個(gè)實(shí)例之間輕松地共享狀態(tài),也可以在一個(gè)應(yīng)用程序的多個(gè)企業(yè)Bean之間共享狀態(tài),它就象為某個(gè)應(yīng)用程序緩存數(shù)據(jù)的類一樣。你可以以單元素集合形式定義類,這樣可以確保在應(yīng)用程序內(nèi)只有一個(gè)緩存實(shí)例,一個(gè)共享狀態(tài)。
使用@Singleton注解定義單元素集合,如:
- @Singleton
- public class PropertiesBean {
- private Properties props;
- public String getProperty(String name) { ... }
- @PostConstruct
- public void initialize { // props = ...}
- }
因?yàn)樗皇橇硪环N會(huì)話Bean,單元素集合可以定義相同的本地和遠(yuǎn)程客戶端視圖,可以象無(wú)狀態(tài)的和有狀態(tài)的Bean那樣,客戶端以訪問(wèn)無(wú)狀態(tài)和有狀態(tài)Bean相同的方式訪問(wèn)單元素集合,即通過(guò)EJB引用。例如,下面是一個(gè)可以訪問(wèn)PropertiesBean單元素集合的客戶端示例:
- @EJB
- private PropertiesBean propsBean;
- ...
- String msg = propsBean.getProperty("hello.message");
在這里,容器確保所有通過(guò)PropertiesBean引用的調(diào)用是由相同的PropertiesBean實(shí)例提供的服務(wù),默認(rèn)情況下,容器強(qiáng)制執(zhí)行和其它組件類型相同的線程保證,換句話說(shuō),單元素集合是全線程安全的,特別值得一提的是,在任一時(shí)刻,允許多個(gè)調(diào)用訪問(wèn)一個(gè)特定的Bean實(shí)例,默認(rèn)情況下,單元素集合會(huì)阻塞所有并發(fā)調(diào)用,但還有其它并發(fā)選項(xiàng)允許更高效地訪問(wèn)單元素集合實(shí)例。
#p#
異步會(huì)話Bean調(diào)用
#t#EJB 3.1引入了一個(gè)強(qiáng)大功能,那就是可以異步調(diào)用會(huì)話Bean方法。對(duì)于一個(gè)異步調(diào)用,允許會(huì)話Bean執(zhí)行它的操作時(shí),客戶端并行處理其它事情。
通過(guò)@Asynchronous注解讓一個(gè)方法支持異步,也可以使用一個(gè)部署描述符將一個(gè)方法指定為異步的。
異步方法可以返回一個(gè)java.util.concurrent.Future<V>或void對(duì)象,F(xiàn)uture<V>對(duì)象容納了異步操作返回的結(jié)果,你可以訪問(wèn)Future<V>對(duì)象檢索一個(gè)結(jié)果值,檢查異?;蛉∠粋€(gè)正在處理中的調(diào)用。Future<V>接口提供一個(gè)get()方法檢索值,當(dāng)然,你也可以其它合適的類檢索值,如AsyncResult<V>,實(shí)際上它自己實(shí)現(xiàn)了一個(gè)Future<V>接口。
在下面的例子中,performCalculation()方法是異步的,它使用AsyncResult<V>類檢索Future<V>對(duì)象返回的值。
- @Stateless
- Public class CalculatorBean implements CalculatorService {
- ...
- @Asynchronous
- public Future<Integer> performCalculation(...) {
- // ... do calculation
- Integer result = ...;
- return new AsyncResult<Integer>(result);
- }
- }
#p#
簡(jiǎn)化打包
EJB規(guī)范始終要求企業(yè)Bean打包到一個(gè)叫做ejb-jar文件的企業(yè)模塊中,因?yàn)樗话阌糜贘ava EE Web應(yīng)用程序,這種打包方法顯得有些累贅,應(yīng)用程序被強(qiáng)制使用一個(gè)Web應(yīng)用程序使用的歸檔文件(.war),一個(gè)企業(yè)Bean使用的ejb-jar文件,還有一個(gè)包含其它包的企業(yè)歸檔文件(.ear),如圖1所示,這種打包方法非常復(fù)雜,它需要指定模塊之間共享的類和資源。
圖 1 傳統(tǒng)的企業(yè)應(yīng)用程序打包方法
EJB 3.1解決了這個(gè)問(wèn)題,簡(jiǎn)化了打包的復(fù)雜程度,徹底消除了企業(yè)Bean類必須打包進(jìn)ejb-jar文件的限制,如圖2所示,現(xiàn)在你可以直接將EJB類放到.war文件中,使用打包Web應(yīng)用程序類相同的打包規(guī)則,這意味著你可以將EJB類放到WEB-INF/classes目錄下,或者放到WEB-INF/lib目錄下的一個(gè).jar文件中。EJB部署描述符也是可選的,如果你需要它,你可以將EJB部署描述符打包到WEB-INF/ejb-jar.xml文件中。
圖 2 簡(jiǎn)化的企業(yè)應(yīng)用程序打包方法
#p#
輕量級(jí)EJB(EJB Lite)
對(duì)許多應(yīng)用程序而言,EJB提供了比應(yīng)用程序真正需要的多得多的功能,使用EJB的應(yīng)用程序通常只需要使用EJB 3.1的一個(gè)子集,輕量級(jí)EJB就是為滿足這種需要誕生的。
輕量級(jí)EJB簡(jiǎn)化了許多開(kāi)發(fā)人員使用EJB,使用輕量級(jí)EJB的開(kāi)發(fā)人員在他們的應(yīng)用程序中需要學(xué)習(xí)使用一部分功能即可。此外,使用輕量級(jí)EJB開(kāi)發(fā)的應(yīng)用程序可以運(yùn)行在輕量級(jí)EJB或全功能EJB 3.1 API實(shí)現(xiàn)的應(yīng)用程序服務(wù)器上。
注意,輕量級(jí)EJB不是一個(gè)產(chǎn)品,它是EJB 3.1 API的一個(gè)子集,輕量級(jí)EJB的目標(biāo)是提供EJB 3.1的一個(gè)子集,滿足大多數(shù)應(yīng)用程序業(yè)務(wù)邏輯層的需要,它也為供應(yīng)商提供了更好的靈活性,為了滿足這些模板,輕量級(jí)EJB提供了以下功能:
1、有狀態(tài),無(wú)狀態(tài)和單元素集合會(huì)話Bean;
2、本地EJB接口或無(wú)接口;
3、攔截器;
4、容器管理的和Bean管理的事務(wù);
5、聲明和編程安全;
6、嵌入式API。
更多EJB 3.1新特性
#t#EJB 3.1除前面談到的這些新特性外,還帶來(lái)了更多的新特性和改進(jìn),例如,它包括一個(gè)用于Java SE環(huán)境的嵌入式API和容器,這些特性使在Java EE容器外(通常指Java SE環(huán)境)測(cè)試EJB組件更容易,另外,EJB 3.1引入的單元素集合為EJB應(yīng)用程序提供了一個(gè)方便的方法,在應(yīng)用程序初始化或關(guān)閉期間接受反饋,默認(rèn)情況下,由容器決定何時(shí)實(shí)例化單元素集合實(shí)例,但你可以通過(guò)@Startup注解,強(qiáng)制容器在應(yīng)用程序初始化期間實(shí)例化單元素集合實(shí)例,允許Bean定義一個(gè)@PostConstruct方法保證在應(yīng)用程序啟動(dòng)時(shí)調(diào)用,此外,@PreDestroy方法可以保證應(yīng)用程序關(guān)閉時(shí)調(diào)用。
【51CTO.com譯稿,非經(jīng)授權(quán)請(qǐng)勿轉(zhuǎn)載。合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com,且不得修改原文內(nèi)容?!?/p>
原文:EJB Technology, Even Easier to Use 作者:Ed Ort