最愛Java

          書山有路勤為徑,學海無涯苦作舟

          《AspectJ Cookbook》讀書筆記十四: 定義方面實例化

          一. 定義單件(singleton)方面
                  通過把issingleton()語句顯示添加到方面聲明中,來顯示建立單件方面實例化策略。

           

          package com.aspectj;

          public aspect Singleton issingleton() {
              
          /**
               * Specifies calling advice whenever a method 
               * matching the following rules gets called:
               * 
               * Class Name: MyClass
               * Method Name:foo
               * Method Return Type:void
               * Method Parameters:an int followed by a String
               
          */

              pointcut callPointCut() : call(
          void MyClass.foo(int,String));
              
              
          //Advice declartion
              before():callPointCut() && !within(Singleton+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice attached to the call point cut");
                  System.out.println(
          "Target: " + thisJoinPoint.getTarget());
                  System.out.println(
          "This: " + thisJoinPoint.getThis());
                  System.out.println(
          "Aspect Instance: " + Singleton.aspectOf());
                  System.out.println(
          "-----------------------------------------");        
              }

          }


                  傳統的面向對象單件的主要缺點是:使用單件的每個類都與單件的公共接口緊密耦合。而面向方面的單件沒有這個缺點。

          二.在每個實例上定義一個方面
                  AspectJ提供了perthis(Pointcut)和pertarget(Pointcut)方面實例化策略,他們依據Pointcut定義選擇的類,來聲明應該為每個新的對象實例所實例化的方面。
                  perthis(Pointcut)聲明和pertarget(Poinitcut)聲明之間的區別必須涉及:在到達通知的連接點時,將會檢查什么對象。perthis(Pointcut)聲明指定:將為通知觸發連接點處的this說引用的每個新對象而實例化一個新的方面。pertarget(Pointcut)實例化策略指定:如果新對象是通知觸發連接點的目標,則為每個這樣的新對象實例化一個新的方面。

           

          package com.aspectj;

          public aspect PerThis perthis(callPointCut()) {
              
          /**
               * Specifies calling advice whenever a method matching the following rules
               * gets called:
               * 
               * Class Name: MyClass Method Name:foo Method Return Type:void Method
               * Parameters:an int followed by a String
               
          */

              pointcut callPointCut() : call(
          void MyClass.foo(int,String));

              
          // Advice declaration
              before():callPointCut()&&!within(PerThis+){
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice attached to the call point cut");
                  System.out.println(
          "Target: " + thisJoinPoint.getTarget());
                  System.out.println(
          "This: " + thisJoinPoint.getThis());
                  System.out.println(
          "Aspect Instance: " + PerThis.aspectOf(thisJoinPoint.getThis()));
                  System.out.println(
          "-----------------------------------------");
              }

          }


                  在考慮可以通過單個方面通知多個類時,perthis(Pointcut)和pertarget(Pointcut)方面實例化策略聲明上的Pointcut參數提供了一些有趣的問題。以下示例中perthis(Pointcut)方面實例化策略只與executeMyClass()切入點指定的MyClass類的對象相關。

           

          package com.aspectj;

          public aspect AdviseMultipleClasses perthis(executeMyClassFoo()){
              
          public pointcut executeMyClassFoo() : execution(void MyClass.foo());
              
              
          public pointcut executeAnotherClassFoo() : execution(void AnotherClass.foo());
              
              before():executeMyClassFoo() 
          {
                  System.out.println(
          "Advising foo");
                  System.out.println(
          "Aspect is: " + this);
              }

              
              before():executeAnotherClassFoo() 
          {
                  System.out.println(
          "Advising foo");
                  System.out.println(
          "Aspect is: " + this);
              }

          }


                  聲明只為executeMyClassFoo()切入點指定的每個新對象實例化AdviseMultipleClasses方面,這隱式排除了其他類的對象。即使聲明了executeAnotherClassFoo()切入點,并且他具有相應的通知,也不會導致把任何方面應用于除了它與executeMyClassFoo()共享的那些類之外的任何類。在示例中,兩個切入點之間沒有共享任何公共類,因此,executeMyClassFoo()切入點及關聯的通知會被忽略,因為這個切入點參與了perthis(Pointcut)實例化策略的定義。

                  一個方面不能具有針對兩類不同對象的兩種實例化策。為了確保方面的實例化策略與它通知的類的素有對象相關,一種有用的技術是:純粹為了使用方面的實例化策略,聲明一個切入點來結合方面中的所有其他的切入點聲明,如:

           

          package com.aspectj;

          public aspect AdviseMultipleClasses perthis(executeMyClassFoo()){
              
          public pointcut executeMyClassFoo() : execution(void MyClass.foo());
              
              
          public pointcut executeAnotherClassFoo() : execution(void AnotherClass.foo());
              
              
          public pointcut applyLifecyclePolicy() : executeMyClassFoo()||executeAnotherClassFoo();
              
              before():executeMyClassFoo() 
          {
                  System.out.println(
          "Advising foo");
                  System.out.println(
          "Aspect is: " + this);
              }

              
              before():executeAnotherClassFoo() 
          {
                  System.out.println(
          "Advising foo");
                  System.out.println(
          "Aspect is: " + this);
              }

          }


          三.在每個控制流程上定義一個方面
                  使用percflow(Pointcut)方面實例化聲明。percflow(Pointcut)語句指示編譯器,它應該為從Pointcut參數指定的連接點集合內進入的每個新控制流程創建方面的一個新實例。

          package com.aspectj;

          public aspect PerControlFlow percflow(callPointCut()){
              
          /**
               * Specifies calling advice whenever a method matching the following rules
               * gets called:
               * 
               * Class Name: MyClass Method Name:foo Method Return Type:void Method
               * Parameters:an int followed by a String
               
          */

              pointcut callPointCut() : call(
          void MyClass.foo(int,String));

              
          // Advice declaration
              before():callPointCut()&&!within(PerControlFlow+){
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice attached to the call point cut");
                  System.out.println(
          "Target: " + thisJoinPoint.getTarget());
                  System.out.println(
          "This: " + thisJoinPoint.getThis());
                  System.out.println(
          "Aspect Instance: " + PerControlFlow.aspectOf());
                  System.out.println(
          "-----------------------------------------");
              }

          }


          percflow(Pointcut)語句代表最細粒度的方面實例化策略,并且會為特定的代碼段創建最大蘇聯高的不同方面實例。

          posted on 2008-08-26 14:37 Brian 閱讀(461) 評論(0)  編輯  收藏 所屬分類: 《AspectJ Cookbook》讀書筆記

          公告


          導航

          <2008年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統計

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 镇平县| 德保县| 泗水县| 惠水县| 诸城市| 平陆县| 碌曲县| 铜川市| 绥中县| 曲周县| 商南县| 绵阳市| 蓬莱市| 乌兰察布市| 宝清县| 常熟市| 军事| 新兴县| 诏安县| 怀仁县| 恩平市| 应城市| 津南区| 溧水县| 孝昌县| 平果县| 左贡县| 玉树县| 甘孜| 双江| 包头市| 道真| 通辽市| 洛川县| 江孜县| 石屏县| 资溪县| 乌兰察布市| 西城区| 镇康县| 安福县|