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

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

JRockit JVM對(duì)AOP的支持,第2部分

2019-11-18 12:23:29
字體:
供稿:網(wǎng)友

  前一篇文章介紹了面向方面編程和關(guān)注點(diǎn)分離的概念,解釋了這種概念如何在方面構(gòu)造的幫助下增強(qiáng)軟件的模塊化,以及如何使用它來補(bǔ)充面向?qū)ο缶幊獭7矫娲砟K化的單元,并且由切點(diǎn)(何處)、建議(什么)以及類型間聲明(在這個(gè)新的方面補(bǔ)充對(duì)象模型)組成。有許多技術(shù)可以將關(guān)注點(diǎn)編織進(jìn)應(yīng)用程序,在當(dāng)今的java領(lǐng)域中,最常用的技術(shù)是字節(jié)碼測(cè)試,在aspectWerkz和AspectJ(從1.1版開始)中實(shí)現(xiàn)了這種技術(shù)。
  
  但是,這種AOP實(shí)現(xiàn)方式具有幾個(gè)缺點(diǎn),本系列的第1篇文章對(duì)此進(jìn)行了具體解釋。盡管在字節(jié)碼測(cè)試領(lǐng)域還有很大的發(fā)展余地(包括Java 5中的JVMTI/JSR-163測(cè)試代理規(guī)范和高效字節(jié)碼操作庫,比如ObjectWeb ASM),但字節(jié)碼測(cè)試代價(jià)不菲。此外,已經(jīng)證實(shí),使用字節(jié)碼測(cè)試實(shí)現(xiàn)AOP是不完善的。例如,假如不采用非常非凡且效率低下的解決方案,就無法通過切點(diǎn)匹配反射式方法調(diào)用或get和set字段。總的來說,所有基于字節(jié)碼測(cè)試的產(chǎn)品都受到字節(jié)碼測(cè)試技術(shù)相關(guān)問題的影響,而且隨著這種技術(shù)的普及,問題將逐漸增加。
  
  所有這些缺點(diǎn)促使JRockit團(tuán)隊(duì)提出了JVM對(duì)AOP的支持。其目標(biāo)是盡可能全面地實(shí)現(xiàn)當(dāng)前的AOP語義,同時(shí)不把JVM限制在某個(gè)特定的面向方面框架的語言細(xì)節(jié)和編程模型上。
  
  本文通過具體的代碼示例介紹該API,然后描述其好處及未來的發(fā)展方向。
  
  我們的動(dòng)機(jī)
  
  讓我們快速地回顧引入JVM的AOP支持的技術(shù)動(dòng)機(jī)。
  
  JVM編織是對(duì)上面提到的問題最自然的解決方案。為了說明其原因,我們將引入兩個(gè)例子,它們說明JVM已經(jīng)完成了編織所涉及的大多數(shù)工作:當(dāng)加載一個(gè)類時(shí),JVM讀取字節(jié)碼,建立為java.lang.reflect.* API進(jìn)行服務(wù)所需的數(shù)據(jù);另一個(gè)例子是方法調(diào)度。目前的JVM將方法或代碼塊的字節(jié)碼編譯為更高級(jí)、效率也更高的構(gòu)造和執(zhí)行流(在適用代碼內(nèi)聯(lián)的地方進(jìn)行代碼內(nèi)聯(lián))。由于HotSwap API的需要,JRockit JVM(可能還包括其他JVM)還會(huì)記錄哪個(gè)方法調(diào)用了其他方法,因此假如在運(yùn)行時(shí)重新定義某個(gè)類,那么在所有期望的位置(內(nèi)聯(lián)的或非內(nèi)聯(lián)的),類中定義的方法主體仍然可以進(jìn)行熱交換。
  
  因此,不必為了編織進(jìn)一個(gè)建議調(diào)用而修改字節(jié)碼,比如說,在特定的方法調(diào)用之前。JVM實(shí)際上可以把握關(guān)于這個(gè)建議調(diào)用的知識(shí),它會(huì)在任何匹配的聯(lián)結(jié)點(diǎn)上對(duì)此建議進(jìn)行調(diào)度,然后再調(diào)度實(shí)際的方法。
  
  由于不接觸字節(jié)碼,立即可以獲得以下好處:
  
  不會(huì)由于字節(jié)碼測(cè)試而產(chǎn)生啟動(dòng)開銷。
  
  對(duì)于在任何位置、任何時(shí)間、以遞增式開銷添加和刪除建議的完全的運(yùn)行時(shí)支持。
  
  對(duì)建議的反射式調(diào)用的隱式支持。
  
  不需要將類模型復(fù)制到特定于框架的某些結(jié)構(gòu),因此減少了額外的內(nèi)存占用。
  
  與JVMDI_EVENT_METHOD_ENTRY或JVMDI_EVENT_FIELD_access等JVMDI規(guī)范中定義的眾所周知的C級(jí)別事件相比,這種方式有很大區(qū)別。在JVMDI中,必須首先處理C級(jí)別API,這使得它對(duì)于大多數(shù)開發(fā)人員來說有些復(fù)雜,而且難以分發(fā)。其次,規(guī)范沒有提供細(xì)粒度的聯(lián)結(jié)點(diǎn)匹配機(jī)制,而是要求預(yù)定所有這樣的事件。這仍然會(huì)導(dǎo)致顯著的開銷,因此不得不進(jìn)行調(diào)試。
  
  我們的方法
  
  我們想讓您先了解一下如何在JVM中添加AOP支持。要害之處在于我們?cè)贘ava API級(jí)別上提供了動(dòng)作調(diào)度和預(yù)定(下面會(huì)具體描述)。因此,您可以寫出下面這樣的代碼:
  
  Weaver w = WeaverFactory.getWeaver();
  Method staticActionMethod =SimpleAction.class.getDeclaredMethod
  ("simpleStaticAction",new Class[0]//no arguments);
  MethodSubscription ms = new MethodSubscription
  (/* where to match*/,InsertionType.BEFORE,staticActionMethod);
  w.addSubscription(ms);
  
  如您所見,我們提供了一個(gè)可訪問的JVM API,可以用它來實(shí)現(xiàn)更傳統(tǒng)的AOP方法。這為解決前面提到的傳統(tǒng)AOP實(shí)現(xiàn)問題提供了極大的靈活性,而且也使其他使用方式成為可能。下面幾節(jié)將具體介紹這個(gè)API。
  
  動(dòng)作調(diào)度和預(yù)定
  
  JRockit JVM AOP支持公開了一個(gè)Java API,它與JVM方法調(diào)度和對(duì)象模型組件緊密集成在一起。為了確保不使JVM被限制在當(dāng)前或未來的任何特定于AOP的技術(shù)方向上,我們決定實(shí)現(xiàn)一個(gè)動(dòng)作調(diào)度和預(yù)定模型。
  
  這個(gè)API使您能夠在指定的切點(diǎn)上描述定義良好的預(yù)定,這樣就能夠注冊(cè)JVM將要調(diào)度的動(dòng)作。動(dòng)作由以下組件組成:
  
  一個(gè)常規(guī)Java方法——我們稱之為動(dòng)作方法,對(duì)于每個(gè)匹配這個(gè)預(yù)定的聯(lián)結(jié)點(diǎn),都將調(diào)用這個(gè)方法。
  
  一個(gè)可選的動(dòng)作實(shí)例,在這個(gè)實(shí)例上調(diào)用動(dòng)作方法。
  
  一組可選的參數(shù)級(jí)注釋,它們向JVM指出動(dòng)作方法期望從調(diào)用堆棧獲得哪些參數(shù)。
  
  動(dòng)作還可以分為before動(dòng)作、after returning動(dòng)作、after throwing動(dòng)作或者instead-of動(dòng)作(類似于AOP的“around”概念)。
  
  為了調(diào)用這個(gè)API,必須獲得一個(gè)jrockit.ext.weaving.Weaver實(shí)例的句柄。這個(gè)編織器實(shí)例根據(jù)它的調(diào)用者上下文來控制答應(yīng)進(jìn)行哪些操作。例如,在容器級(jí)編織器可以預(yù)定特定于應(yīng)用程序的聯(lián)結(jié)點(diǎn)時(shí),用戶可能不希望部署在應(yīng)用服務(wù)器中的應(yīng)用程序創(chuàng)建編織器,從而預(yù)定某些容器級(jí)或特定于JDK的聯(lián)結(jié)點(diǎn)的動(dòng)作方法。這種編織器可見性理念反映了底層類加載器的委托模型。
  
  我們簡(jiǎn)單介紹一下這些構(gòu)造如何映射到常規(guī)的AOP構(gòu)造,這有助于理解這個(gè)模型:
  
  ·預(yù)定可以視為一個(gè)有類型的聯(lián)結(jié)點(diǎn),或者就是一個(gè)有類型的聯(lián)結(jié)點(diǎn)(字段get()、set()、方法call()等等),加上一個(gè)within()/withincode()切點(diǎn)。
  
  ·動(dòng)作實(shí)例可以視為方面實(shí)例。
  
  ·動(dòng)作方法可以視為建議。
  
  熟悉AOP的讀者可能已經(jīng)看出,要想用這個(gè)JVM級(jí)API實(shí)現(xiàn)一個(gè)完整的AOP框架,還需要進(jìn)行一些開發(fā),包括一個(gè)(按照規(guī)定)治理方面實(shí)例化模型的中間層、cflow()切點(diǎn)的實(shí)現(xiàn)以及切點(diǎn)的完全合成和正交的實(shí)現(xiàn)。
  
  API細(xì)節(jié):動(dòng)作方法
  
  動(dòng)作方法(與AOP的建議概念相似)就像(作為方面的)常規(guī)類的常規(guī)Java方法。它可以是static方法,也可以是成員方法。它的返回類型必須符合某些隱式約定,而且before動(dòng)作的返回類型應(yīng)該是void。對(duì)于instead-of動(dòng)作(類似于AOP的around建議語義),其返回類型還是作為動(dòng)作調(diào)用結(jié)果的堆棧的類型。
  
  動(dòng)作方法可以有參數(shù),參數(shù)的注釋進(jìn)一步控制上下文公開,如下面的代碼示例所示:
  
  import java.lang.reflect.*;
  import jrockit.ext.weaving.*;
  public class SimpleAction
  { public static void simpleStaticAction()
  {out.  }
  public void simpleAction() {out.println("hello action!");
  }
  public void simpleAction(@CalleeMethod WMethod calleeM,@CallerMethod WMethod callerM)
  {out.println(callerM.getMethod().getName());
  out.println(" calling ");
  out.println(calleeM.getMethod().getName());
  }
  }
  該代碼示例引入了jrockit.ext.weaving.WMethod類。該類用作java.lang.reflect.Method、java.lang.reflect.ConstrUCtor和類的靜態(tài)初始化器(它在java.lang.reflect.*中沒有出現(xiàn))的包裝器。這與AspectJ JoinPoint.StaticPart.getSignature()抽象化相似。
  
  下面是當(dāng)前定義的注釋及其含義。
  
[[The No.1 Picture.]]

  為了支持instead-of,并能夠決定是否沿著截取鏈前進(jìn)(就像在AOP中通過JoinPoint.proceed()概念實(shí)現(xiàn)),我們引入了jrockit.ext.weaving.InvocationContext構(gòu)造,如下所示:
  
  import jrockit.ext.weaving.*;
  
  public class InsteadOfAction {
  
  public Object instead(
  InvocationContext jp,
  @CalleeMethod Method callee) {
  return jp.proceed();
  }
  }
  
  API的細(xì)節(jié):動(dòng)作實(shí)例和動(dòng)作類型
  
  正如前面代碼示例中所示,動(dòng)作方法可以是靜態(tài)的,也可以不是。假如動(dòng)作方法不是靜態(tài)的,那么就必須傳遞一個(gè)動(dòng)作實(shí)例,JVM在這個(gè)實(shí)例上調(diào)用動(dòng)作方法。
  
  其語法風(fēng)格與Java開發(fā)人員使用java.lang.reflect.Method.invoke(null/*static method*/, .../*args*/)對(duì)方法進(jìn)行反射式調(diào)用一樣。但是,利用JVM的AOP支持,底層的動(dòng)作調(diào)用根本不涉及任何反射。
  
  答應(yīng)用戶控制動(dòng)作實(shí)例,就會(huì)產(chǎn)生有趣的用例。例如,可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的委托模式,在運(yùn)行時(shí)用另一個(gè)實(shí)現(xiàn)替換整個(gè)動(dòng)作實(shí)例,而不涉及JVM的內(nèi)部組件。
  
  注重,這將有助于(按照規(guī)定)實(shí)現(xiàn)AOP方面實(shí)例化模型,比如issingleton()、pertarget()、perthis()、percflow()等等,同時(shí)不會(huì)將JVM API限制在某些預(yù)定義的語義上。
  
  在將預(yù)定注冊(cè)到編織器實(shí)例之前,賦予它一個(gè)類型作為建議類型:before、instead-of、after-returning或after-throwing。
  
  可以編寫下面這樣的代碼來創(chuàng)建預(yù)定:
  
  // Get a Weaver instance that will act as a
  // container for the subscription(s) we create
  Weaver w = WeaverFactory.getWeaver();
  
  // regular java.lang.reflect is used to refer
  // to the action method "simpleStaticAction()"
  Method staticActionMethod =
  SimpleAction.class.getDeclaredMethod(
  "simpleStaticAction",
  new Class[0]//no arguments
  );
  
  MethodSub

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 吴川市| 邵武市| 黑水县| 山西省| 伊通| 河西区| 三都| 古交市| 民县| 灌阳县| 黔西| 定兴县| 庐江县| 余干县| 牟定县| 敦化市| 宁明县| 玉环县| 芜湖县| 北海市| 新建县| 兴文县| 洱源县| 江安县| 乡城县| 甘肃省| 峡江县| 张家界市| 枣阳市| 休宁县| 岑巩县| 十堰市| 略阳县| 上林县| 永泰县| 平阴县| 临潭县| 仙居县| 白山市| 襄垣县| 榆树市|