国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

面向方面編程AOP和JBoss(一)

2019-11-18 13:04:52
字體:
供稿:網(wǎng)友

  概述
  面向方面編程(aspect-Oriented PRogramming, AOP)是一個(gè)令人興奮的新模式。就開發(fā)軟件系統(tǒng)而言,它的影響力將會(huì)和有15到20年的面向?qū)ο笠粯印C嫦蚍矫婢幊毯兔嫦驅(qū)ο缶幊滩坏皇腔ハ喔?jìng)爭(zhēng)的技術(shù)而且是可以很好的互補(bǔ)。面向?qū)ο缶幊讨饕糜跒橥粚?duì)象層次的公用行為建模。它的弱點(diǎn)是將公共行為應(yīng)用于多個(gè)無關(guān)對(duì)象模型之間。而這恰恰是AOP適合的地方。AOP答應(yīng)定義交叉的關(guān)系,那些關(guān)系應(yīng)用于跨國(guó)分開的,非常不同的對(duì)象模型。AOP答應(yīng)你層次化功能性而不是嵌入功能性,那使得代碼有更好的可度性和易于維護(hù)性。我喜歡認(rèn)為OOP是自上而下的軟件開發(fā),而AOP是自左而右的軟件開發(fā),它們是完全直交的技術(shù),并且互相很好的補(bǔ)充。
  在OOP的工具里是繼續(xù),封裝和多態(tài),而AOP的組件是通知/攔截器,導(dǎo)言,元數(shù)據(jù)和pintcuts.讓我們看一下這些定義。
  
  通知/攔截器
  一個(gè)通知是一個(gè)邏輯,這個(gè)邏輯有特定的事件觸發(fā)。它是行為,這個(gè)行為能夠被插入在調(diào)用者和被調(diào)用者之間,在一個(gè)方法調(diào)用者和實(shí)際的方法之間。通知是AOP真正的要害。通知答應(yīng)你去透明的應(yīng)用一些事物,像日志和記錄到一個(gè)存在的對(duì)象模型。
  在 JBoss AOP中,我們用攔截器是實(shí)現(xiàn)了通知。你能夠定義攔截器,它攔截方法調(diào)用,構(gòu)造器調(diào)用和域訪問。后面,我們將闡明怎樣應(yīng)用這些攔截器到一個(gè)存在的對(duì)象模型。
  
  導(dǎo)言
  導(dǎo)言是一個(gè)增加方法或者域到一個(gè)存在的類中的途徑。它們甚至答應(yīng)你改變當(dāng)前存在的類是顯的接口,并且引入一個(gè)混合的類,這個(gè)類是實(shí)現(xiàn)了新的接口。導(dǎo)言答應(yīng)你帶入多繼續(xù)到一般的java類。導(dǎo)言一個(gè)主要的用例是當(dāng)你有一個(gè)方面,你想讓這個(gè)方面有一個(gè)運(yùn)行時(shí)間借口時(shí)。你想應(yīng)用你的方面跨越不同的對(duì)象層次,但是你仍然要應(yīng)用開發(fā)者去能夠調(diào)用特定方面的APIs.
  Apple apple    = new Apple();
  LoggingAPI logging = (LoggingAPI)apple;
  Apple.setLoggingLevel(VERBOSE);
  導(dǎo)言能夠是一個(gè)方法,它將一個(gè)新的API綁定到一個(gè)存在的對(duì)象模型。
  
  元數(shù)據(jù)
  元數(shù)據(jù)是能夠綁定到一個(gè)類的附加信息,在靜態(tài)或者運(yùn)行時(shí)間。元數(shù)據(jù)更加有力力量的是,你能夠動(dòng)態(tài)綁定元數(shù)據(jù)到一個(gè)給定的對(duì)象實(shí)例。元數(shù)據(jù)非常強(qiáng)大的,當(dāng)你真正編寫應(yīng)用于任何對(duì)象的一般方面,而邏輯需要知道制定類的信息時(shí)。在使用的一個(gè)好的元數(shù)據(jù)類比就是EJB規(guī)范。在EJB的xml發(fā)布描述符中,你需要定義基于每一個(gè)方法的事務(wù)屬性。應(yīng)用服務(wù)器指導(dǎo)什么時(shí)候,什么地方開始,掛起或者提交一個(gè)事務(wù),因?yàn)槟阍贐EAN的XML的配置文件中的元數(shù)據(jù)內(nèi)已經(jīng)定義如方法:Required,RequiresNew,Support等等,它們綁定在你的EJB類和事務(wù)治理之間。
  C#把元數(shù)據(jù)成為了這個(gè)語言的組成部分。XDoclet是另一個(gè)動(dòng)作的元數(shù)據(jù)的例子。假如你曾經(jīng)用過XDoclet生成過EJB文件和發(fā)布描述符,你就會(huì)知道元數(shù)據(jù)的力量。在JDK1.5中,當(dāng)元數(shù)據(jù)被加入java語言中,JCP一致同意。(見JSR175)。盡管直到JSR175成為了事實(shí),一個(gè)好的AOP框架也應(yīng)該提供一種機(jī)制去定義在運(yùn)行時(shí)間有效的類級(jí)元數(shù)據(jù)。
  
  Pointcuts
  假如攔截器,導(dǎo)言和元數(shù)據(jù)是AOP的特征,那么pointcuts就是粘合劑。Pointcuts告訴AOP框架,那些攔截器綁定到那些類, 什么原數(shù)據(jù)將應(yīng)用于那些類或者那一個(gè)導(dǎo)言將被傳入那些類。Pointcuts定義各種AOP特征將怎樣應(yīng)用于你應(yīng)用中的類。
  
  在動(dòng)作中的AOP
  例1.使用攔截器
  JBoss 4.0帶了一個(gè)AOP框架。這個(gè)框架和JBoss應(yīng)用服務(wù)器緊密地結(jié)合,但是你也能夠在你的應(yīng)用中,單獨(dú)的運(yùn)行它。直到你看了動(dòng)作中看到它,你才會(huì)完全的理解這個(gè)概念,所以讓我們用一個(gè)來自于JBoss AOP的例子,來說明這個(gè)模塊所有的部分是如何一起工作的。在這章余下的部分,我們將建立一個(gè)例子來跟蹤使用AOP的框架。
  
  定義一個(gè)攔截器
  為了實(shí)現(xiàn)我們對(duì)于框架的跟蹤,我們必須作的第一件事是定義一個(gè)攔截器,它將作實(shí)際的工作。在JBOSS AOP中,所有的攔截器必須實(shí)現(xiàn)org.jboss.aop.Interceptor 接口。
  public interface Interceptor
  {
    public String getName();
    public InvocationResponse invoke(Invocation invocation) throws Throwable;
  }
  
  在JBoss AOP中,被攔截的所有域,構(gòu)造器和方法被轉(zhuǎn)成一般的invoke調(diào)用。方法的參數(shù)被填入一個(gè)Invocation對(duì)象,并且方法的返回值,域的存取或者構(gòu)造器被填入一個(gè)InvocationResponse對(duì)象。這個(gè)Invocation對(duì)象也驅(qū)動(dòng)這個(gè)攔截鏈。為了清楚地說明這個(gè),讓我們看一下,在這個(gè)例子中,所有的對(duì)象是如何配合到一起的。
  import org.jboss.aop.*;
  import java.lang.reflect.*;
  
  public class TracingInterceptor implements Interceptor
  {
    public String getName() { return TracingInterceptor; }
    public InvocationResponse invoke(Invocation invocation)
      throws Throwable
    {
     String message = null;
  
     if (invocation.getType() == InvocationType.METHOD)
     {
       Method method = MethodInvocation.getMethod(invocation);
       message    = method: + method.getName();
     }
     else if (invocation.getType() == InvocationType.CONSTRUCTOR)
     {
       Constructor c = ConstructorInvocation.getConstructor(invocation);
       message    = constructor: + c.toString();
     }
     else
     {
       // Do nothing for fields. Just too verbose.
       //對(duì)于域什么也不做。太繁瑣。
       return invocation.invokeNext();
     }
  
     System.out.println(Entering + message);
  
     // Continue on. Invoke the real method or constructor.
     // 繼續(xù)。調(diào)用真正的方法或者構(gòu)造器
     InvocationResponse rsp = invocation.invokeNext();
     System.out.println(Leaving + message);
     return rsp;
    }
  }
  
  上面的攔截器將攔截所有的對(duì)一個(gè)域,構(gòu)造器或方法的調(diào)用。假如調(diào)用的類型是一個(gè)方法或者構(gòu)造器,一個(gè)帶有方法或構(gòu)造器簽名的消息將輸出到控制平臺(tái)。
  
  綁定攔截器
  好了,這樣我們就定義了攔截器。但是怎么綁定這個(gè)攔截器到實(shí)際的類?為了做這個(gè),我們需要定義一個(gè)pointcut。對(duì)于JBoss AOP, pointcuts 是在一個(gè)XML文件中定義的。讓我們看一下這看起來象什么。
  
  
  
   
     
      
     

   

  
  
  上面的pointcut綁定TracingInterceptor到一個(gè)叫做POJO的類。這看起來有一點(diǎn)麻煩;我們不得不為每一個(gè)想跟蹤的類創(chuàng)建一個(gè)pointcut嗎?幸運(yùn)的是,interceptor-pointcut的類屬性可以用任何的正規(guī)表達(dá)式。所以假如你想跟蹤由JVM載入的類,類表達(dá)式將變?yōu)?.*。假如你僅僅想跟蹤一個(gè)特定的包,那么表達(dá)式將是com.acme.mypackge.*。
  當(dāng)單獨(dú)運(yùn)行JBoss AOP時(shí),任何符合 META-INF/jboss-aop.xml模式的XML文件將被JBoss AOP 運(yùn)行時(shí)間所載入。假如相關(guān)的路徑被包含在任何JAR或你的CLASSPATH的目錄中,那個(gè)特定的XML文件將在啟動(dòng)時(shí),由JBoss AOP 運(yùn)行時(shí)間所載入。
  
  運(yùn)行這個(gè)例子
  我們將用上面定義的pointcut去運(yùn)行例子。POJO類看起來如下:
  
  [code]public class POJO
  {
    public POJO() {}
    public void helloWorld() { System.out.println(Hello World!); }
    public static void main(String[] args)
    {
     POJO pojo = new POJO();
     pojo.helloWorld();
    }
  }
  [/code]
  TracingInterceptor將攔截對(duì)main(),POJO()和helloWorld()的調(diào)用。輸出看起來如下:
  Entering method: main
  Entering constructor: public POJO()
  Leaving constructor: public POJO()
  Entering method: helloWorld
  Hello World!
  Leaving method: helloWorld
  Leaving method: main
  
  你能夠在這里下載JBoss AOP和離子代碼。編譯和執(zhí)行:
  
  $ cd oreilly-aop/example1
  $ eXPort CLASSPATH=.;jboss-common.jar;jboss-aop.jar;javassist.jar
  $ javac *.java
  $ java -Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader POJO
  
  JBoss AOP 對(duì)綁定的攔截器做字節(jié)碼操作。因?yàn)闆]有編譯步驟,AOP運(yùn)行時(shí)間必須有ClassLoader的總控。假如你正運(yùn)行在非JBoss應(yīng)用服務(wù)器,你必須用JBoss制定的一個(gè)類載入器覆蓋系統(tǒng)的類載入器。
  TraceingInterceptor不跟蹤域訪問,因?yàn)樗幸稽c(diǎn)繁瑣。對(duì)于開發(fā)者,實(shí)現(xiàn)get()和set()方法去封裝域訪問是一個(gè)一般的實(shí)踐。假如TracingInterceptor能夠過濾出,并且不跟蹤這些方法,那是非常好的。這個(gè)例子顯示你能夠用JBoss AOP 元數(shù)據(jù)去實(shí)現(xiàn)基于任一方法的過濾。一般,元數(shù)據(jù)用于更復(fù)雜的事情,如定義事務(wù)屬性,每個(gè)方法的安全角色或者持久性映射,但是這個(gè)例子應(yīng)該足夠說明元數(shù)據(jù)能夠怎樣用在 AOP使能的應(yīng)用中。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 锡林浩特市| 梁山县| 七台河市| 沙田区| 磐安县| 大同县| 南开区| 喀什市| 东乌| 黄平县| 叶城县| 隆昌县| 石景山区| 泾阳县| 肥乡县| 凉城县| 蛟河市| 阿克苏市| 黔东| 吉林市| 汉川市| 巨鹿县| 凤台县| 道孚县| 东港市| 安徽省| 平乡县| 涿鹿县| 扎鲁特旗| 德兴市| 阳新县| 西安市| 平乡县| 荃湾区| 西平县| 太保市| 太康县| 新平| 拉萨市| 玛纳斯县| 浦东新区|