麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > ASP > 正文

EJB 3.0+Aspect實(shí)現(xiàn)聲明性編程初步

2024-07-21 02:15:04
字體:
供稿:網(wǎng)友
  提要 本文將與你一同探討怎樣把注解和方面的威力聯(lián)合起來,以與ejb 3.0兼容的方式為企業(yè)實(shí)現(xiàn)提供聲明性服務(wù),而在同時(shí)仍然提供容器的獨(dú)立性。

  一、 引言

  在我們共同尋求進(jìn)一步提高軟件開發(fā)生產(chǎn)性能的方法的過程中,我們-作為java社團(tuán)成員-一般都轉(zhuǎn)向j2ee來提供針對(duì)企業(yè)開發(fā)中更具挑戰(zhàn)性的技術(shù)問題如分布式事務(wù)管理、并發(fā)性和對(duì)象分布等的解決方案。其背后的指導(dǎo)思想-這些復(fù)雜的企業(yè)服務(wù)能被應(yīng)用程序服務(wù)器供應(yīng)商所實(shí)現(xiàn)并能為商業(yè)開發(fā)者所平衡-的確是一種很好的思想。j2ee,具體地說是ejb,已成功地提供了一個(gè)平臺(tái)-在其上構(gòu)建企業(yè)java應(yīng)用程序。

  這其中部分的成功是由于能夠進(jìn)行聲明性編程-一種程序開發(fā)方式-用這種方式,你可以聲明基礎(chǔ)結(jié)構(gòu)服務(wù)而不是用商業(yè)邏輯明確地編碼從而使代碼散布于各處。ejb已經(jīng)證明了這種編程方式的價(jià)值-通過允許企業(yè)問題例如事務(wù)和安全被用一種發(fā)布描述符所聲明并為容器所處理。

  然而,在過去的歲月中,越來越多的開發(fā)者認(rèn)識(shí)到ejb在團(tuán)隊(duì)的生產(chǎn)效率方面給它自己帶來新的大量的挑戰(zhàn)-每個(gè)ejb必須伴隨多個(gè)接口,以一種發(fā)布描述符描述,經(jīng)由jndi被存取,等等。而在容器外ejb上進(jìn)行單元測(cè)試也帶來另外的困難,如今ejb已不再把重點(diǎn)放在單純的面向?qū)ο箝_發(fā)上。

  請(qǐng)注意,為閱讀本文您需具備如下工具:

  ·java 2 sdk 1.5

  ·maven 2.0 beta 2

  ejb 3.0的目標(biāo)在于從以下幾個(gè)方面使企業(yè)開發(fā)更為容易:

  ·通過引入元數(shù)據(jù)注解來實(shí)現(xiàn)聲明性請(qǐng)求企業(yè)服務(wù)

  ·經(jīng)由注解實(shí)現(xiàn)依賴性/資源注入

  ·實(shí)現(xiàn)企業(yè)beans與ejb特定接口的解耦

  ·經(jīng)由輕量級(jí)的對(duì)象關(guān)系映射實(shí)現(xiàn)持續(xù)性存儲(chǔ)的簡(jiǎn)化

  這對(duì)于ejb開發(fā)者來說尤如一股春風(fēng)-一直以來,他們竭力地從事開發(fā)、測(cè)試和維護(hù)ejb。利用ejb 3.0寫一個(gè)企業(yè)bean現(xiàn)在變得很容易,就如用特定的注解創(chuàng)建一個(gè)pojo(傳統(tǒng)的java對(duì)象)以把它標(biāo)明為一個(gè)ejb并請(qǐng)求企業(yè)服務(wù)。下面是一個(gè)來自于ejb 3.0 public draft中ejb的例子:

@stateful
public class cartbean implements shoppingcart
{
private float total;
private vector productcodes;
public int someshoppingmethod(){...};
...
}


  ejb 3.0聲明中實(shí)質(zhì)上指明開發(fā)者需要的不是一重量級(jí)的、"一次發(fā)布滿足所有"的解決方案,而是一個(gè)輕量級(jí)的、容易使用的解決方案-為開發(fā)者提供一定范圍的企業(yè)服務(wù)。為此,ejb 3.0所提供的最重要的方法之一就是實(shí)現(xiàn)企業(yè)beans與ejb api的解耦。并且,此解決方案還帶來令人感興趣的衍生-ejb現(xiàn)在不僅能夠運(yùn)行在不同的ejb容器上,而且還能運(yùn)行于任何應(yīng)用程序框架內(nèi)部-這些框架必須能夠識(shí)別ejb 3.0(jsr 220)和用于聲明企業(yè)服務(wù)的普通注解(jsr 250)。

  本文沒有提供關(guān)于聲明性編程、ejbs、方面或注解的深度探索。相反,而只是分析一下這些技術(shù)之間的相互關(guān)系并討論如何把它們用一種新的方式結(jié)合起來以簡(jiǎn)化應(yīng)用程序開發(fā)。

  在本文中,你將會(huì)學(xué)習(xí)到如何編寫一個(gè)ejb 3.0兼容的bean并且通過創(chuàng)建幾個(gè)簡(jiǎn)單的方面使其具有聲明性事務(wù)管理、安全和資源注入等功能。我希望您能從這個(gè)練習(xí)中得到以下的受益:

  ·學(xué)習(xí)方面的三個(gè)實(shí)際應(yīng)用(依賴性注入、安全和事務(wù))。

  ·熟悉ejb 3.0及其背后的思想。

  ·認(rèn)識(shí)到怎樣實(shí)現(xiàn)ejb與特定api的解耦以允許ejb 3.0兼容的服務(wù)能夠以輕量級(jí)實(shí)現(xiàn)而不是僅由ejb來提供。

  二、 實(shí)例應(yīng)用程序-航班訂購

  在整個(gè)后面的討論中,你將學(xué)習(xí)到一個(gè)航班訂購系統(tǒng)的實(shí)現(xiàn)-它使用方面和注解來實(shí)現(xiàn)依賴性注入、安全和事務(wù)管理。該應(yīng)用程序僅執(zhí)行兩項(xiàng)功能:它允許用戶搜索航班(圖1),然后訂購一次旅行(圖2)。這兩個(gè)操作都將被進(jìn)行安全處理以僅允許能被識(shí)別的用戶來執(zhí)行它們。另外,既然"訂購旅行"操作包含訂購兩個(gè)航班(外出和返回航班),那么需要把該操作創(chuàng)建為事務(wù)性的-如,兩個(gè)訂購將作為一個(gè)工作單元要么都成功要么都失敗。


圖1.航班查詢:首先,用戶查找滿足他們的指定標(biāo)準(zhǔn)的航班。

圖2.航班訂購:接下來,用戶訂購一個(gè)外出航班和一個(gè)返回航班。兩個(gè)訂購要么都成功要么都失敗。

  這個(gè)簡(jiǎn)單的web應(yīng)用程序包含幾個(gè)servlet、一個(gè)服務(wù)外觀和一個(gè)dao層(見圖3)。

  資源配置、安全性和事務(wù)管理等橫切關(guān)注點(diǎn)將由方面(用aspectj 1.5 m3實(shí)現(xiàn))所提供以實(shí)現(xiàn)在java 5注解中所聲明的注入行為。


圖3.航班訂購系統(tǒng)架構(gòu):這個(gè)航班訂購系統(tǒng)包括三個(gè)主要組成組件-它們聯(lián)合起來共同完成用戶請(qǐng)求。
  三、 資源注入

  ejb 3.0草案聲明中允許資源經(jīng)由@resource注解來聲明(這一決定定義在草案普通注解聲明中)并且被容器注入進(jìn)你的ejb。依賴性注入是一項(xiàng)技術(shù)-使用這種技術(shù),一個(gè)對(duì)象外部的實(shí)體而不是顯式地為該對(duì)象所創(chuàng)建的實(shí)體能夠提供(注入)一個(gè)對(duì)象的依賴性。它有時(shí)被描述為好萊塢原則-這開玩笑似地意味著"不要給我們打電話,我們會(huì)給你打電話的"。

  以travelagencyserviceimpl類為例-這個(gè)類為了持續(xù)性存儲(chǔ)一些數(shù)據(jù)需要找到一個(gè)iflightdao接口的實(shí)現(xiàn)。傳統(tǒng)地,這是經(jīng)由一個(gè)工廠、singleton、服務(wù)定位器或一些另外的定制解決方案來實(shí)現(xiàn)的。其中,一個(gè)可能的解決方案看上去如下所示:

public class travelagencyserviceimpl implements itravelagencyservice
{
 public iflightdao flightdao;
 public travelagencyserviceimpl()
 { flightdao = flightdaofactory.getinstance().getflightdao(); }
 public void booktrip(long outboundflightid, long returnflightid, int seats)
 throws insufficientseatsexception
 {
  reserveseats(outboundflightid, seats);
  reserveseats(returnflightid, seats);
 }
}


  你已看到,這個(gè)實(shí)現(xiàn)包含創(chuàng)建一個(gè)特定的工廠類-它很可能讀取存儲(chǔ)在某處的配置信息以了解要?jiǎng)?chuàng)建iflightdao的實(shí)現(xiàn)方式。如果不是讓服務(wù)顯式地創(chuàng)建它的由容器所注入的依賴性,那么配置細(xì)節(jié)和對(duì)象創(chuàng)建將被代理到容器上。這允許一個(gè)應(yīng)用程序中的組件能夠被容易地連接到一起-用不同的配置并且消除大量老式的singleton和工廠代碼。

  該類的一個(gè)實(shí)現(xiàn)-它依賴于一個(gè)用jsr 250資源注解所聲明的iflightdao的實(shí)現(xiàn)-可能看上去如下所示:

public class travelagencyserviceimpl implements itravelagencyservice
{
 @resource(name = "flightdao")
 public iflightdao flightdao;
 public void booktrip(long outboundflightid, long returnflightid, int seats)
 throws insufficientseatsexception
 {
  reserveseats(outboundflightid, seats);
  reserveseats(returnflightid, seats);
 }
}


  在這種情況下,容器將把一個(gè)命名為"flightdao"的資源的正確實(shí)現(xiàn)提供給服務(wù)類。但是,如果你現(xiàn)在就想利用資源注入,而不是等待ejb 3.0發(fā)行版,又該如何呢?好,你可以采用一種輕量級(jí)的容器-它能夠提供例如spring或pico container的依賴性注入。然而,當(dāng)前我還不了解存在一個(gè)輕量級(jí)的容器-它能夠使用jsr 250資源注解以指定注入要求(盡管我非常盼望在這一方面出現(xiàn)一些)。

  一種解決方案是使用方面來實(shí)現(xiàn)依賴性注入。如果你為此使用@resource注解,那么你的實(shí)現(xiàn)將與ejb 3.0方式一致并且向前兼容ejb 3.0實(shí)現(xiàn)-而實(shí)現(xiàn)這并不是很困難的事情。下列列表顯示用aspectj創(chuàng)建的一個(gè)方面-它注入用@resource注解所注解的字段:

@aspect
public class injectionaspect
{
 private dependencymanager manager = new dependencymanager();
 @before("get(@resource * *.*)")
 public void beforefieldaccesses(joinpoint thisjoinpoint)
 throws illegalargumentexception, illegalaccessexception
 {
  fieldsignature signature = (fieldsignature) thisjoinpoint.getsignature();
  resource injectannotation = signature.getfield().getannotation(resource.class);
  object dependency = manager.resolvedependency(signature.getfieldtype(),injectannotation.name());
  signature.getfield().set(thisjoinpoint.getthis(), dependency);
 }
}


  這個(gè)簡(jiǎn)單方面所做的全部是,從一個(gè)屬性文件(這個(gè)邏輯被封裝在dependencymanager對(duì)象中)查詢實(shí)現(xiàn)類并且在存取字段之前把它注入到用@resource注解所注解的字段中。顯然,這種實(shí)現(xiàn)不是完整的,但是它確實(shí)說明了你可以怎樣以一種jsr 250兼容方式且不需采用ejb來提供資源注入。

  四、 安全性

  除了資源注入外,jsr 250和ejb 3.0還提供經(jīng)由注解的元數(shù)據(jù)安全表示。javax.annotation.security包定義了五個(gè)注解-runas,rolesallowed,permitall,denyall和rolesreferenced-所有這些都能應(yīng)用到方法上來定義安全要求。例如,如果你想要聲明上面列出的bookflight方法僅能為具有"user"角色的調(diào)用者所執(zhí)行,那么你可以用如下的安全約束來注解這個(gè)方法:

public class travelagencyserviceimpl implements itravelagencyservice
{
 @resource(name = "flightdao")
 public iflightdao flightdao;
 @rolesallowed("user")
 public void booktrip(long outboundflightid, long returnflightid, int seats)
 throws insufficientseatsexception
 {
  reserveseats(outboundflightid, seats);
  reserveseats(returnflightid, seats);
 }
}


  這個(gè)注解將指出由容器來負(fù)責(zé)保證只有指定角色的調(diào)用者才能執(zhí)行這個(gè)方法。因此現(xiàn)在我將展示另一個(gè)簡(jiǎn)單的方面-它將進(jìn)一步加強(qiáng)在該應(yīng)用程序上的安全約束:

@aspect
public class securityaspect
{
 @around("execution(@javax.annotation.security.rolesallowed * *.*(..))")
 public object aroundsecuredmethods(proceedingjoinpoint thisjoinpoint)
 throws throwable
 {
  boolean callerauthorized = false;
  rolesallowed rolesallowed = rolesallowedforjoinpoint(thisjoinpoint);
  for (string role : rolesallowed.value())
  {
   if (callerinrole(role))
   { callerauthorized = true; }
  }
  if (callerauthorized)
  { return thisjoinpoint.proceed(); }
  else
  {
   throw new runtimeexception("caller not authorized to perform specified function");
  }
 }
 private rolesallowed rolesallowedforjoinpoint(proceedingjoinpoint thisjoinpoint)
 {
  methodsignature methodsignature = (methodsignature) thisjoinpoint.getsignature();
  method targetmethod = methodsignature.getmethod();
  return targetmethod.getannotation(rolesallowed.class);
 }
 private boolean callerinrole(string role)
 { ... }
}


  這個(gè)方面包含了所有方法的執(zhí)行-通過核實(shí)該調(diào)用者是在注解中所指定的角色之一,用@rolesallowed注解來注解并且保證調(diào)用者被授權(quán)調(diào)用該方法。當(dāng)然你還能代之以任何你喜歡的算法來授權(quán)用戶并且檢索他/她的角色,例如jaas或一個(gè)定制的解決方案。在本示例程序中,為方便起見,我選擇代理到servlet容器。

  五、 事務(wù)

  事務(wù)成為企業(yè)開發(fā)的一個(gè)重要部分-因?yàn)樗鼈冇兄谠谝粋€(gè)并發(fā)的環(huán)境中的數(shù)據(jù)集成。從一個(gè)高層次上看,事務(wù)可以通過多種或者是完整的或者是都不完整的操作來保證這一點(diǎn)。

  不象針對(duì)資源注入和安全的注解,針對(duì)事務(wù)的注解是特定于ejb 3.0的并且沒有在jsr 250普通注解中定義。ejb 3.0定義了兩個(gè)與事務(wù)相聯(lián)系的注解:transactionmanagement和transactionattribute。該transactionmanager注解指定事務(wù)是由容器所管理還是為bean所管理的。在ejb 3中,如果這個(gè)注解沒被指定,那么將使用容器所管理的事務(wù)。transactionattribute注解用于指定方法的事務(wù)傳播級(jí)別。有效值-包括強(qiáng)制的、要求的、要求新的、支持的、不支持的和從不支持的-用來定義是否要求一個(gè)已有事務(wù)或啟動(dòng)一個(gè)新的事務(wù),等等。

  因?yàn)閎ookflight操作包含兩步-訂購一個(gè)外出航班和一個(gè)返回航班,所以,通過把它包裝成一個(gè)事務(wù),你能保證這項(xiàng)操作的一致性。通過使用ejb 3.0事務(wù)注解,這將看上去如下所示:

public class travelagencyserviceimpl implements itravelagencyservice
{
 @resource(name = "flightdao")
 public iflightdao flightdao;
 @rolesallowed("user")
 @transactionattribute(transactionattributetype.required)
 public void booktrip(long outboundflightid, long returnflightid, int seats)
 throws insufficientseatsexception
 {
  reserveseats(outboundflightid, seats);
  reserveseats(returnflightid, seats);
 }
}


  并且你可以應(yīng)用一個(gè)簡(jiǎn)單的方面來自動(dòng)地界定事務(wù)邊界:

@aspect
public class transactionaspect
{
 @pointcut("execution(@javax.ejb.transactionattribute * *.*(..))")
 public void transactionalmethods(){}
 @before("transactionalmethods()")
 public void beforetransactionalmethods()
 { hibernateutil.begintransaction(); }
 @afterreturning("transactionalmethods()")
 public void afterreturningtransactionalmethods()
 { hibernateutil.committransaction(); }
 @afterthrowing("transactionalmethods()")
 public void afterthrowingtransactionalmethods()
 { hibernateutil.rollbacktransaction(); }
}


  這個(gè)實(shí)現(xiàn)基于這樣的假設(shè)-hibernate和無所不在的線程本地模式被用于管理hibernate會(huì)話和事務(wù)對(duì)象;但是,任何其它適當(dāng)?shù)膶?shí)現(xiàn),例如基于jta的實(shí)現(xiàn),都能被代替使用。

  六、 小結(jié)

  通過使用ejb 3.0和jsr 250注解集,本文已經(jīng)展示了例如資源管理、安全和事務(wù)等橫切關(guān)注點(diǎn)是怎樣被實(shí)現(xiàn)為方面的。當(dāng)然,還有許多內(nèi)容我們需進(jìn)一步學(xué)習(xí)。首先要學(xué)的就是通過使用aspectj的實(shí)現(xiàn)這些示例方面為模塊化橫切關(guān)注點(diǎn)所提供的藍(lán)圖。其次,我們已經(jīng)看到了在如今正浮出水面的ejb 3.0聲明背后的一些新思想和新概念。最后,我們還以戲劇性的方式看到了從ejb api中解耦我們的商業(yè)對(duì)象所必須要提供的自由。在這一點(diǎn)上,所有你想使travelagencyserviceimpl成為一個(gè)無狀態(tài)會(huì)話要做的僅是添加一條最后的注解:

@stateful
public class travelagencyserviceimpl implements itravelagencyservice
{ ... }


  最后,我非常希望這種自由地提供企業(yè)服務(wù)的方式會(huì)帶來框架/容器工業(yè)界的競(jìng)爭(zhēng)和革新。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91久久久久久久一区二区 | 日韩视频在线观看免费视频 | 在线观看免费毛片视频 | 欧美成人综合视频 | 毛片电影在线看 | 久草在线最新免费 | 一级毛片免费高清视频 | 西川av在线一区二区三区 | 一区二区三区四区视频在线观看 | 在线无码 | 久色乳综合思思在线视频 | 欧美一级α| 久久国产精品99国产 | 久久亚洲精品国产一区 | 毛片哪里看 | 草久免费| 成年人黄色免费网站 | 免费欧美一级视频 | 精品国产九九九 | 狠狠干狠狠操 | 午夜精品毛片 | 91精品国产777在线观看 | 国产成人在线免费视频 | 免费视频a | 精品久久久久久中文字幕 | 黄色大片高清 | 亚洲第一成人在线视频 | 国产精品久久久久久久不卡 | 国产日韩线路一线路二 | 欧美亚州 | 91情侣偷在线精品国产 | 717影院理论午夜伦八戒秦先生 | 欧美性黄 | 日韩在线欧美在线 | 九色com | 欧美黄成人免费网站大全 | 99影视电影电视剧在线播放 | 国产99视频精品免视看9 | 成人在线免费观看视频 | 亚洲视频在线观看免费 | 国产免费一级淫片a级中文 99国产精品自拍 |