欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

EJB 3.1 新特性介紹(一)

系統(tǒng) 1914 0

引言

Enterprise Java Beans(簡稱EJB)是Java Enterprise Edition(簡稱Java EE)平臺上的服務端組件架構(gòu)模型,目標極力于快速并簡化分布式,事務處理,安全以及便攜式的應用程序。

EJB在其2.*時代也叱詫風云過,由于能夠解決許多企業(yè)應用程序的需求而被廣泛采納。但這只是EJB成功的表象,越來越多的質(zhì)疑聲開始抨擊EJB的復雜。“缺乏好的持久層策略,又臭又長的布署描述符,能力有限的單元測試”等等這些常用卻又不好用的技術導致了大量開發(fā)人員開始尋找新的“輪子”。

Sun的反應的確有些遲鈍,但還是它花費大量精力來修訂規(guī)范,使得EJB得到很大的改觀。EJB3擯棄了許多現(xiàn)有的缺點,呈現(xiàn)給開發(fā)人員的解決方案在社區(qū)中大受好評。EJB又一次變成了切實可行的解決方案,并且現(xiàn)在已經(jīng)有許多放棄它的團隊,再次接收EJB。

雖然它成功了,但EJB3還沒有當初預計的那么理想。反觀EJB2.1,新規(guī)范要面對兩個主要的挑戰(zhàn):

1. 為了改變EJB2.1現(xiàn)有的特性, ( 比如說需要強大的持久層框架來代替 Entity Beans ;支持使用 Annotation 來代替布署描述符;拋棄 home interface 等等。 ) ,需要進行大量的重建工作。

2. 為了引入新的解決方案,需要加入原先規(guī)范中沒有的新技術。( 比如說支持 Singletons ;支持方法攔截;支持異步調(diào)用;改進并增強現(xiàn)有的 Timer Service 特性

對于EJB,優(yōu)先考慮的就是全部重建。“我們只有先清空杯子里的水,才能接納新的東西”。現(xiàn)在杯子已經(jīng)清空了,這對我們來說是非常有利的,而且還可以沒有包袱的大膽前進。

EJB3.1 又一次引入了一系列新的特性,傾向于挖掘技術的潛力。依我來看,EJB3.1絕對是一個重要的發(fā)布版本,它將那些長期讓人渴望的特性帶到開發(fā)者面前,更加能夠滿足最新的企業(yè)應用程序開發(fā),同時對EJB再次被人們采納將做出巨大的貢獻。

近期,EJB 3.1提議最終草案已經(jīng)發(fā)布了,現(xiàn)在我們已經(jīng)非常接近最終發(fā)行版了。本文會貫穿大多數(shù)新的特性,對每一個新特性都有會有一定程度的介紹。

No-Interface View(非接口視圖)

EJB3.1引入了no-interface view的概念——將一個bean的所有的public method通過一個Local View暴露出來。 ( 具體訪問可見參見本文后面的 Global JNDI names ) Session Beans并不強迫你再去實現(xiàn)任何接口。EJB容器提供一個指向no-interface view的引用實現(xiàn),允許客戶端調(diào)用該bean的任何public method,并且no-interface view也可以確保事務,安全以及攔截的行為與原先的用法一致。

通過non-interface view,所有bean的public method(當然也包括定義在其父類上的public method)都是可用的。一個客戶端可以通過依賴注入或JNDI lookup得到該view的引用,用起來感覺就好像它是local或remote的view一樣。

但與local和remote的view不同的是, local remote view 必須與其所實現(xiàn)的的業(yè)務接口同時存在 ,而no-interface view的引用則只是bean這個類本身。注意, no-interface view 不再依賴于接口

下面的代碼樣例說明了一個servlet使用no-interface view是一件多么容易事啊。這個被引用的no-interface view叫作ByeEJB,其實就是一個普普通通的JavaBean。該EJB并未實現(xiàn)任何接口,也沒有提供什么多余的布署描述符。最后但并不是最不重要的一點就是,這里EJB引用的獲得使用了依賴注入進行簡化。

Java代碼 收藏代碼
  1. ByeServlet
  2. (...)
  3. @EJB
  4. privateByeEJBbyeEJB;
  5. publicStringsayBye(){
  6. StringBuildersb=newStringBuilder();
  7. sb.append("<html><head>");
  8. sb.append("<title>ByeBye</title>");
  9. sb.append("</head><body>");
  10. sb.append("<h1>"+byeEJB.sayBye()+"</h1>");
  11. sb.append("</body></html>");
  12. returnsb.toString();
  13. }
  14. (...)
  15. ByeEJB
  16. @Stateless
  17. publicclassByeEJB{
  18. publicStringsayBye(){
  19. return"Bye!";
  20. }
  21. }

實際上如果引用類型為java類而不是接口的話,還是有些硬性的限制條件:

l 客戶端永遠無法使用new操作符來獲得引用。 ( 很明顯如果是你自己 new 出來的, EJB 容器自然無法托管 )

l 除了public method外,如果其它方法如果出錯,也會拋出EJBException異常。

l 一個指向該view的引用可以作為任何本地接口或其它no-interface view方法的參數(shù)進行傳遞或返回。

如果bean沒有暴露任何local或remote view,則容器必須默認提供一個可用的no-interface view。如果bean提供了至少一個local或remote view,則窗口不會提供no-interface view(除非使用@LocalBean顯式要求提供).

Bean和其父類的所有public method都會通過no-interface view被暴露出來。這也意味著任何public callback method也會暴露出來,因此在使用的時候要注意這一點。

本特性避免了接口的編寫,簡化了程序的開發(fā)(實際上并不是所有的類都需要接口)。也許在不久的將來還會加入remote no-interface view。

Singleton

大多數(shù)的應用程序都有過至少需要一個singleton bean ( 對每個應用程序來說,它意味著只需要初始化一次 ) 的經(jīng)歷。許多供應商已經(jīng)滿足了這方面的需求,通過使用描述布署符來限定一個bean所允許的最大實例數(shù)量。供應商這種“各自為政”的方式破壞了JAVA到處宣揚的“一次編寫,到處布署”的口號,因此迫切的再推出一套類似特性的規(guī)范來很有必要。EJB 3.1最終還是引入了singleton session beans。

現(xiàn)在主流的session beans有三類——stateless,stateful 和 singleton。Singleton session beans可通過使用Singleton Annotation來標注,然后每個應用程序會確保只實例化一次。Singleton session beans支持與客戶端共享,當然也支持并發(fā)訪問 ( 后面有會具體談到 )

singleton bean的生命周期始于容器下列任意初始化階段:

1. 直接實例化某個singleton

2. 通過依賴注入實例化某個singleton,這樣其依賴的那些singleton也會被跟著實例化,如此遞推下去。

3. 通過執(zhí)行PostConstruct回調(diào)

缺省情況下,容器有義務決定singleton bean何時被創(chuàng)建 ( 比如在 spring 中,默認是將所有的 singleton 在啟動時就初始化 ) ,但是也允許開發(fā)人員使用Startup annotation在應用程序啟動時,要求容器去對singleton進行初始化。此外,Startup annotation還允許你去定義singleton beans之間的依賴關系。當容器開始處理任何客戶端發(fā)過來的請示時,所有標注有startup的singletons都必須初始化完成。

下面的代碼樣例大致演示了依賴是如何實現(xiàn)的。singleton A的沒有使用@Startup也沒有別的singleton依賴于它,于是A的實例化由容器來決定 ( 說白了,此時 A 的實例化由具體 EJB 實現(xiàn)來決定,規(guī)范沒有硬性規(guī)定 ) 。singleton B在應用程序啟動過程中被實例化,但必須早于singleton D和singleton E ( 很明顯,沒有 B 的實例, C D 可能都無法正常初始化 ) 。即使這個時候的B沒有使用@Startup,但由于有其它的singletons依賴于它,它還是要先實例化的。singleton C由于使用了@Startup,它會在應用程序啟動過程中被實例化,但必須比singleton E先完成。同理D也必須在E之前完成實例化。因此,E是應用程序中會最后一個被初始化。 ( 注意,再重申一下 A 是否會初始化與供應商的實現(xiàn)有關,也許供應商的實現(xiàn)是預先加載,也許是延遲加載,但當你真正使用 A 的時候,肯定會保證被初始化了 )

Java代碼 收藏代碼
  1. @Singleton
  2. publicclassA{(...)}
  3. @Singleton
  4. publicclassB{(...)}
  5. @Startup
  6. publicclassC{(...)}
  7. @Startup(DependsOn="B")
  8. @Singleton
  9. publicclassD{(...)}
  10. @Startup(DependsOn=({"C","D"})
  11. @Singleton
  12. publicclassE{(...)}

有一點需要注意的是,如果一個bean依賴于多個bean的注入,那么這些被依賴的beans之間的初始化時機是不確定的。E依賴于C和D,并沒有說C一定要在D之前被實例化,除非D本身也是依賴于C的。

singleton可以@Startup定義依賴于現(xiàn)存其它模塊中的singletons。

當應用程序關閉時,容器有義務執(zhí)行singletons的PreDestory回調(diào),將所有的singletons全部銷毀。這個時候,啟動時候的依賴關系在銷毀時變得有意義了,比如說A依賴于B,當A被銷毀時,B還是存活的,剛好與初始化相反。

Singleton bean會維護服務端與客戶端調(diào)用而產(chǎn)生的狀態(tài),但當應用程序關閉或容器掛掉時,該狀態(tài)并不會保存下來。 ( 大家一定想到這種情況如果使用序列化機制將狀態(tài)保存下來,然后當程序再次啟動時,再反序列化還原狀態(tài)也是一種選擇。不過,至于你 singleton 中裝的是什么內(nèi)容,是否需要被序列化,是否可以被序列化對容器來說還是未知數(shù),所以干脆掛就掛吧。 ) 為了處理服務端與客戶端的并發(fā)調(diào)用問題,開發(fā)人員必須定義一個并發(fā)策略。規(guī)范中定義了兩種方式:

l CMC(Container-managed concurrency 容器托管的并發(fā)機制):顧名思義,由容器來管理該bean實例的并發(fā)調(diào)用。這也是EJB的默認策略。

l BMC(Bean-managed concurrency Bean托管的并發(fā)機制):容器此時并不會干涉該bean實例的并發(fā),把并發(fā)的同步調(diào)用推回給開發(fā)人員。BMC允許使用合法的同步原語(如synchronized 和volatile關鍵字),來協(xié)調(diào)不同客戶端不同線程對同一個singleton的并發(fā)訪問。

( 呵呵,這不正是聲明式與編程式的又一次實踐嗎 ? )

大多數(shù)情況下,CMC肯定是首選。容器的管理并發(fā)問題時,還是使用“Lock (鎖)”。每個方法都關聯(lián)上一個read lock和write lock。Read lock表示應該方法可以盡可能的被多個線程并發(fā)調(diào)用,而write lock表示該方法在每次只能每一個線程訪問。

缺省情況下,lock的屬性值是write。當然你可以通過使用@Lock來修改默認屬性值。@Lock可以用于類,接口和方法。如其它Annotation類似,@Lock也有繼承性。在類級別使用@Lock,它的所有相關方法也會被應用上,除非你單獨限制某一個具體的方法。

當某個方法持有 write lock時,容器只允許其中一個并發(fā)線程去調(diào)用該方法。其它線程并必須等待,直到該方法再次變得可用。客戶端的等待也許是無限期的,這個時候可以使用@ AccessTimeout來指定一個最大等待時間。如果超時了,會拋出ConcurrentAccessTimeoutException異常。

下面的代碼示例中演示了如果使用CMC。Singleton A明確指定為CMC( 盡管這么沒有必要,因為默認就是 CMC ,主要還是為了演示 )。Singleton B并未定義任何并發(fā)策略,但按照規(guī)范,它還是屬性CMC范疇,它的所有方法顯示指定CMC使用 write lock方式。Singleton C與Singleton B幾乎一模一樣,只是使用的是read lock方式。Singleton D和Singleton C一樣,但是D中的sayBye方法重新定義為 write lock。Singleton E總要是演示@AccessTimeout的使用,當有因等待E中某方法而被阻塞的客戶端超過10秒時,就會招出ConcurrentAccessTimeoutException異常。

Java代碼 收藏代碼
  1. @Singleton
  2. @ConcurrencyManagement(CONTAINER)
  3. publicclassA{(...)}
  4. @Singleton
  5. @Lock(WRITE)
  6. publicclassB{(...)}
  7. @Singleton
  8. @Lock(READ)
  9. publicclassC{(...)}
  10. @Singleton
  11. @Lock(READ)
  12. publicclassD{
  13. (...)
  14. @Lock(WRITE)
  15. publicStringsayBye(){(...)}
  16. (...)
  17. }
  18. @Singleton
  19. @AccessTimeout(10000)
  20. publicclassE{(...)}

如果是在集群環(huán)境下,當應用程序布署在不同的JVM上,則每個JVM都有該singleton的一個實例。

直到EJB 3,任何由EJB拋出系統(tǒng)異常都會導致實例被廢棄和銷毀。但這個原則并不適用于singleton beans——它們必須一直存活下來,至少應用程關閉時才銷毀。因此任何在業(yè)務對像方法或回調(diào)拋出系統(tǒng)異常時,業(yè)務對象并不會被銷毀。

與 stateless beans一樣,singletons也可以暴露成web services。

Asynchronous Invocations( 異步調(diào)用 )

Session beans方法的異步調(diào)用是這些新特性中最重要的特性之一。它可以應用于所有類型的session beans。規(guī)范規(guī)定:在容器開始執(zhí)行某個bean實例的調(diào)用之前,異步調(diào)用的控制權(quán)一定要返回給客戶端。這又將session beans提高到了一個嶄新的高度——使有潛在異步調(diào)用需求開發(fā)人員從session beans中獲得更多好處,也允許客戶端觸發(fā)并行處理的流程。

通過使用@Asynchronous就可以將一個類或方法標記為異步調(diào)用。下面的示例演示了該annotation不同場合下的應用。Bean A將其所有方法標注為異步;SingletonB中,只有定義的flushBye方法才是異步的;對stateless C而言,所有的通過local interface Clocal接口調(diào)用的方法都是異步的;而通過Cremote接口調(diào)用卻是同步的。因此,同一個方法還可能由于所引用的不同接口而表現(xiàn)出不同的行為。最后,bean D的flushBye肯定是異步的,于Dlocal是否是不是異步已經(jīng)無關了。

Java代碼 收藏代碼
  1. @Stateless
  2. @Asynchronous
  3. publicclassA{(...)}
  4. @Singleton
  5. publicclassB{
  6. (...)
  7. @Asynchronous
  8. publicvoidflushBye(){(...)}
  9. (...)
  10. }
  11. @Stateless
  12. publicclassCimplementsCLocal,CRemote{
  13. publicvoidflushBye(){(...)}
  14. }
  15. @Local
  16. @Asynchronous
  17. publicinterfaceCLocal{
  18. publicvoidflushBye();
  19. }
  20. @Remote
  21. publicinterfaceCRemote{
  22. publicvoidflushBye();
  23. }
  24. @Stateless
  25. publicclassDimplementsDLocal{(...)}
  26. @Local
  27. publicinterfaceDLocal{
  28. (...)
  29. @Asynchronous
  30. publicvoidflushBye();
  31. (...)
  32. }

注意異步方法調(diào)用的返回類型必須是void或Future<V>(其中V表示返回值的類型)。如果方法的返回值為void,則不允許聲明任何應用程序異常。

Future接口在Java 5 中就被引入,提供四個主要方法:

  • cancel(booleanmayInterruptIfRunning):嘗試取消異步方法的執(zhí)行。如果某個bean的實例方法還未開始調(diào)用,容器會嘗試取消這個調(diào)用。 如果為參數(shù)為 true:執(zhí)行中的任務可以被interrupt;如果參數(shù)為false:允許這個任務執(zhí)行完畢 。標志位“mayInterruptIfRunning”用于控制目標bean是否對客戶端是否可見,免得該異步調(diào)用被客戶端不小心給取消了。
  • get:當方法調(diào)用完成時,返回結(jié)果。該get方法有兩個重載版本,一個是調(diào)用后一直處于阻塞狀態(tài),直到方法調(diào)用完成;另一個則可以設置一個超時的參數(shù)。
  • isCancelled:指示該方法是否被取消。
  • isDone:指示該方法是否執(zhí)行完成。

規(guī)范要求容器提供AsyncResult<V>類作為Future<V>接口的實現(xiàn),它可以將執(zhí)行后的返回結(jié)構(gòu)作為構(gòu)造函數(shù)的參數(shù),請看下面代碼:

Java代碼 收藏代碼
  1. @Asynchronous
  2. publicFuture<String>sayBye(){
  3. Stringbye=executeLongQuery();
  4. returnnewAsyncResult<String>(bye);
  5. }

Future<V>的返回類型因不同的客戶端角度而異。因此,如果在一個標有@Asynchronous

接口中定義了方法m,那么請注意,只有這個接口中的方法允許返回類型為Future<V>,在其它別的非異步接口中的定義中不能帶有Future<V>,只能返回普通的V( 注意 V 在這里表示的是泛型 )。請看下面示例:

Java代碼 收藏代碼
  1. @Stateless
  2. publicclassByeEJBimplementsByeLocal,ByeRemote{
  3. publicStringsayBye(){(...)}
  4. }
  5. @Local
  6. @Asynchronous
  7. publicinterfacesayBye{
  8. publicFuture<String>flushBye();
  9. }
  10. @Remote
  11. publicinterfaceByeRemote{
  12. publicStringsayBye();
  13. }

SessionContext接口有一個wasCancelCalled方法,用于判斷客戶端是否調(diào)用了Future和cancel方法。如果Future的cancel方法的mayInterruptIfRunning參數(shù)設置為true,那么wasCancelCalled自然也會返回true,也就是說異步調(diào)用被終止了。( 也就是說 SessionContext 可以用于判斷某個異步方法是否被取消,提高程序的健壯性 )。請看代碼示例:

Java代碼 收藏代碼
  1. @Resource
  2. SessionContextctx;
  3. @Asynchronous
  4. publicFuture<String>sayBye(){
  5. Stringbye=executeFirstLongQuery();
  6. if(!ctx.wasCancelCalled()){
  7. bye+=executeSecondLongQuery();
  8. }
  9. returnnewAsyncResult<String>(bye);
  10. }

( 下面代碼似乎有筆誤,根本無法通過編譯 )

如果異步方法拋出了一個普通應用程序異常,則這個異常傳播到客戶端時必須為ExecutionException。原始的異常信息仍然可以通過調(diào)用getCause來獲得的。

Java代碼 收藏代碼
  1. @Stateless
  2. publicclassByeEJBimplementsByeLocal{
  3. publicStringsayBye()throwsMyException{
  4. thrownewMyException();
  5. }
  6. }
  7. @Local
  8. @Asynchronous
  9. publicinterfaceByeLocal{
  10. publicFuture<String>sayBye();
  11. }
  12. //Client
  13. @Stateless
  14. publicclassClientEJB{
  15. @EJB
  16. ByeLocalbyeEjb;
  17. publicvoidinvokeSayBye(){
  18. try{
  19. Future<String>futStr=byeEjb.sayBye();
  20. }catch(ExecutionExceptionee){
  21. StringoriginalMsg=ee.getCause().getMessage();
  22. System.out.println("Originalerrormessage:"+originalMsg);
  23. }
  24. }
  25. }

對于異步方法的執(zhí)行,客戶端的事務上下文并不會傳播到。因此,當下列異步事務方法調(diào)用時,可以得到的結(jié)論分別為:

  • 如果方法m的事務屬性定義為“REQUIRED”,那么它的表現(xiàn)形式將永遠為“REQUIRES_NEW”。
  • 如果方法m的事務屬性定義為“MANDATORY”,那么它的表現(xiàn)形式永遠是拋出TransactionRequiredException異常。
  • 如果方法m的事務屬性定義為“SUPPORTS”,那么它的表現(xiàn)形式永遠是不會參與在事務上下文中。

EJB 3.1 新特性介紹(一)


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 真实做爰对白录音 | 亚洲草原天堂 | 一区二区三区在线视频播放 | 久久一日本道色综合久久 | 麻豆传媒地址 | aⅴ免费在线观看 | 成人黄色免费 | 欧美视频在线免费 | 成人超碰 | 日韩免费网站 | 日韩欧美专区 | 亚洲精品a级 | 国产精品久久久久久婷婷天堂 | 91看片淫黄大片欧美看国产片 | 精品一区二区三区在线视频 | 韩国成人毛片aaa黄 人人天天操 | 久久精品视频5 | 国产在线a | 久草电影天堂 | 99爱国产| 欧美三级免费看 | 欧美亚洲专区 | 中国美女撒尿txxxxx视频 | 日韩av资源站 | 精品久久一区二区 | 精品国产一区二区三区久久 | 青草九九 | 色婷婷久久综合中文久久一本 | 日韩一级欧美一级毛片在线 | 欧美爽爽爽高清免费视频 | 久久久久国产精品免费免费搜索 | 免费在线成人av | 国产免费一区 | 一级片免费播放 | 欧美一级黄色免费看 | 亚洲国产网站 | 一区二区三区回区在观看免费视频 | 日本黄色免费网站 | 久久精品视频16 | 亚洲午夜日韩高清一区 | 91欧美精品综合在线观看 |