最愛Java

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

          一.繼承切入點定義
                  創建一個抽象類。使用合適的public、protected或default訪問修飾符在抽象方面內定義可重用的切入點邏輯。最后,把抽象方面繼承進子方面中,以重用聲明的切入點。

          package com.aspectj;

          public abstract aspect BasePointcutDefinitionsAspect {
              
          public pointcut callPointcut() : call(void MyClass.foo(int,String));
          }

           

          package com.aspectj;

          public aspect ReusePointcutsRecipe extends BasePointcutDefinitionsAspect {
              
          //Advice declaration
              before():callPointcut()&&!within(ReusePointcutsRecipe+{
                  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(
          "-----------------------------------------");        
              }

          }




          二.實現抽象切入點
                  在聲明切入點和周圍的方面時,使用abstract關鍵字,并且不要提供任何切入點邏輯。

          package com.aspectj;

          public abstract aspect BaseAbstractAspect {
              
          /**
               * Specifies an abstract pointcut placeholder
               * for derived aspects to specify
               
          */

              
          public abstract pointcut abstractBasepointcut();
              
              
          /**
               * Specifies calling advice whenever a join point
               * picked by the abstractBasePointcut (specified
               * by specialized aspects) is encountered, and not within
               * this aspect or any inheriting aspects.
               
          */

              pointcut runAdvicePointcut() : abstractBasepointcut() 
          && !within(BaseAbstractAspect+);
          }

           

          package com.aspectj;

          public aspect AbstractImplementationAspect extends BaseAbstractAspect {
              
          /**
               * Specifies calling advice whenever a method
               * matching the following rules gets called:
               * 
               * Class Name: MyClass
               * Method Name:foo
               * Method Return:void
               * Method Parameters:an int followed by a string
               
          */

              
          public pointcut abstractBasepointcut():call(void MyClass.foo(int,String));
              
              
          //Advice declaration
              before():runAdvicePointcut(){
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Location: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");            
              }


          }


          三.把類繼承進方面中
              使用extends關鍵字來聲明方面擴展類。示例為一個偽日志記錄類,它代表一種現有的日志記錄機制。其目標是:重構對應用程序中日志記錄類的所有現有的調用,并把日志記錄模塊化進一個方面中,它可以更靈活地織入進應用程序中。

          package com.aspectj;

          public class OOLogging {
              
          public void logEntry(String entry) {
                  System.out.println(
          "Entry logged: " + entry);
              }

          }

           

          package com.aspectj;

          public aspect AOLogging extends OOLogging{
              
          /**
               * Specifies calling advice whenever a method
               * matching the following rules gets called:
               * 
               * Class Name: MyClass
               * Method Name:foo
               * Method Return:void
               * Method Parameters:an int followed by a string
               
          */

              pointcut callPointcut() : call(
          void MyClass.foo(int,String));
              
              
          //Advice declaration
              before():callPointcut()&&!within(AOLogging+)&&!within(AOLogging) {
                  
          this.logEntry(thisJoinPoint.toShortString());
              }

          }


           

          posted @ 2008-08-26 15:34 Brian 閱讀(284) | 評論 (0)編輯 收藏

          一. 定義單件(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 @ 2008-08-26 14:37 Brian 閱讀(461) | 評論 (0)編輯 收藏
               摘要: 一.訪問類成員  package com.aspectj; public privileged aspect MemberAccessRecipe {     /** *//**      * Specifies&nb...  閱讀全文
          posted @ 2008-08-26 13:45 Brian 閱讀(1560) | 評論 (1)編輯 收藏
               摘要: 一.捕獲何時連接點上的運行時條件評估為true     使用if(Expression)語句來評估包含要比較的運行時變量的布爾表達式。if(Expression)語句的語法如下:     pointcut <pointcut name>(<any values to be picked up>...  閱讀全文
          posted @ 2008-08-25 20:40 Brian 閱讀(419) | 評論 (0)編輯 收藏
               摘要:          this([Type | Identifier])研究的是在捕捉的連接點處由this引用的對象的類型。連接點的目標(通過target([Type | Identifier])切入點指定)依賴于連接點類型而有所不同,但它常常是在其上調用方法的對象,或者是以某種方式訪問的在其中遇到連接點的屬性。...  閱讀全文
          posted @ 2008-08-25 15:11 Brian 閱讀(291) | 評論 (0)編輯 收藏

              本章中描述的切入點支持捕獲另一個初始連接點作用域或環境內的所有連接點。每個連接點在程序的控制流程中都有一個具體位置,這為通過這里描述的切入點聲明捕獲的連接點提供了環境。
              一. 捕獲通過初始連接點開始的程序控制流程內的所有連接點
              使用cflow(Pointcut)切入點。cflow(Pointcut)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : cflow(<pointcut>);

              cflow(Pointcut)切入點具有3個關鍵特征:
                  1.cflow(Pointcut)切入點捕獲在初始特定的連接點環境內遇到的所有連接點,這個初始連接點是通過另一個切入點選擇的。
                  2.捕獲的連接點包括初始連接點。
                  3.作用域是cflow(pointcut)切入點中重要的鑒別器。這個切入點將捕獲通過切入點參數捕獲的連接點的控制流程內的所有連接點。


          package com.aspectj;

          public aspect CFlowRecipe {
              
          /**
               * 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 callInitialPointcut():call(
          void MyClass.foo(int,String));
              
              
          /**
               * Specifies calling advice whenever a join point is encountered
               * including and after the initial join point triggers the pointcut
               * that is specified in the parameter:
               * 
               * Pointcut Name:callInitialPointcut
               
          */

              pointcut cflowPointcut():cflow(callInitialPointcut());
              
              
          //Advice declaration
              before() : cflowPointcut() && !within(CFlowRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by CFlowRecipe()");
                  System.out.println(
          "Join Point Kind: " + thisJoinPoint.getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }
              
              

          }



                  值得更詳細研究cflow(Pointcut)做什么。這個特殊的切入點引入了連接點環境的概念。它是指每個連接點具有一個作用域,在這個用途域內,它被看成是執行程序的控制流程的一部分。
                  在這個控制流程內,任何遇到的連接點都會觸發cflow(Pointcut)切入點,并調用任何關聯的通知。當初始連接點觸發指定的切入點參數時,cflow(Pointcut)切入點會起作用,并觸發其關聯的通知。然后,將為在初始連接點環境內的控制流程中遇到的每個連接點調用與cflow(Pointcut)關聯的通知。最后,捕獲的連接點集合包括初始連接點本身,這就是這個切入點與cflowbelow(Pointcut)切入點之間的主要區別。

                  在cflow(Pointcut)的當前實現中,在使用它時,其實現方式會引入大量的系統開銷。在可能的地方,并且連接點重用不受影響時,可以考慮優先使用withincode(Signature)切入點。

              二.捕獲程序控制流程內的所有連接點,不包括初始連接點
              使用cflowbelow(Pointcut)切入點。cflowbelow(Pointcut)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : cflowbelow(<pointcut>);


          package com.aspectj;

          public aspect CFlowBelowRecipe {
              
          /**
               * 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 callInitialPointcut():call(
          void MyClass.foo(int,String));
              
              
          /**
               * Specifies calling advice whenever a join point is encountered
               * after the initial join point triggers the pointcut
               * that is specified in the parameter:
               * 
               * Pointcut Name:callInitialPointcut
               
          */

              pointcut cflowPointcut():cflowbelow(callInitialPointcut());
              
              
          //Advice declaration
              before() : cflowPointcut() && !within(CFlowBelowRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by CFlowBelowRecipe()");
                  System.out.println(
          "Join Point Kind: " + thisJoinPoint.getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }
              
              

          }



              這里和第一部分介紹的內容有點區別;其區別是實際捕獲的連接點數量。cflow(Pointcut)切入點會觸發在初始連接點環境內遇到的所有連接點(包括初始連接點)上的通知,而cflowbelow(Pointcut)切入點則不包括那個初始連接點。

          posted @ 2008-08-25 10:36 Brian 閱讀(422) | 評論 (0)編輯 收藏

              切入點定義設計中的常用方式是:基于關注的程序作用域,限制捕獲連接點的范圍。這可以讓你即使控制在進一步的切入點定義中將會涉及哪些連接點。
              本章中的切入點相當容易理解,并且他們是AspectJ中一些常用的元素。例如,廣泛使用的within(TypePattern)切入點將以!within(%THIS_ASPECT%)形式使用它。這個AspectJ術語限制了當前方面之外的每個連接點的作用域,從而可以防止通知觸發對相同通知塊的遞歸調用,并導致一個無限循環。
              一. 捕獲特定類中的所有連接點
              使用within(TypePattern)切入點,利用TypePattern指定特定類類型模式,within(TypePattern)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : within(<class>);

              within(TypePattern)切入點具有3個關鍵特征:
                  1.within(TypePattern)切入點捕獲指定類作用域中的所有連接點。
                  2.within(TypePattern)切入點極少孤立使用。相反,它通常與切入點結合使用,用于減少將觸發附帶通知的連接點。
                  3.TypePattern可以包含通配符,用于選擇不同類上的一系列連接點。


           

           

          package com.aspectj;

          public aspect WithinClassRecipe {
              
          /**
               * Specifies calling advice on any join point encountered within
               * the defined scope:
               * 
               * Scope:MyClass
               
          */

              pointcut withinMyClass() : within(MyClass);
              
              
          //Advice declaration
              before() : withinMyClass() && !within(WithinClassRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by withinMyClass()");
                  System.out.println(
          "Join Point Kind: " + thisJoinPoint.getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }


          }



          二. 捕獲特定包中的所有連接點
              within(TypePattern)切入點提供一種有用的手段,它使用通配符在出現在每個類中的連接點中指定一個關注。可以在TypePattern中使用合適的通配符,從切入點邏輯的余下部分中包含或排除連接點的整個包。

          package com.aspectj;

          public aspect WithinPackageRecipe {
              
          /**
               * Specifies calling advice on any join point encountered within
               * the defined scope:
               * 
               * Scope:packageA
               
          */

              pointcut withinPackageA() : within(packageA.
          *);
              
              
          //Advice declaration
              before() : withinPackageA() && !within(WithinPackageRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by WitinPackageRecipe()");
                  System.out.println(
          "Join Point Kind: " + thisJoinPoint.getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }


          }


           

          三. 捕獲特定方法內的所有連接點
              使用withincode(Signature)切入點。withincode(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : withincode(<modifier> <class>.<method>(<paramter types>));

              withincode(Signature)切入點有3個關鍵特征:
                  1. withincode(Signature)切入點指定了特定方法的本地作用域內的所有連接點。
                  2. withincode(Signature)切入點極少孤立使用。相反,他通常與其他切入點結合使用,用于減少將觸發附帶通知的連接點。
                  3. Signaure可以包含通配符,用于選擇不同類的不同方法上的一系列連接點。

          package com.aspectj;

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

              pointcut withinFooIntStringAnyReturnPointcut() : withincode(
          * MyClass.foo(int,String));
              
              
          //Advice declaration
              before() : withinFooIntStringAnyReturnPointcut() && !within(WithinMethodRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by withinMyClass()");
                  System.out.println(
          "Join Point Kind: " + thisJoinPoint.getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }


          }

          posted @ 2008-08-25 10:32 Brian 閱讀(336) | 評論 (0)編輯 收藏

          一. 捕獲何時訪問對象的屬性
              使用get(Signature)切入點。get(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : get(<optional modifier> <type> <class>.<field>);
              get(Signature)具有4個關鍵特征:
              1.get(Signature)切入點會觸發直接在其中(而不僅僅是在訪問器方法的調用上)訪問屬性的通知。
              2.get(Signature)切入點不能捕獲對靜態屬性的訪問,盡管從AspectJ的語法角度講以這種方式定義切入點是完全合法的。
              3.Signature必須解析成特定類的屬性。
              4.Signature可以包含通配符,用于選擇不同屬性上的一系列連接點。

          package com.aspectj;

          public aspect GetRecipe {
              
          /**
               * Specifies calling advice whenever an attribute matching the following rules
               * is accessed:
               * 
               * Type:String 
               * Class Name:MyClass 
               * Attribute Name:name
               
          */

              pointcut getNamePointcut(): get(String MyClass.name);
              
              
          // Advice declaration
              before():getNamePointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by getNamePointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }

          }

              你可能期待類使用static和final關鍵字定義一個常量屬性,這樣,在訪問這個常量時你就可能使用get(Signature)切入點來捕獲。
              

          package com.aspectj;

          public aspect GetConstant {
              
          /**
               * Specifies calling advice whenever an attribute matching the following rules
               * is accessed:
               * 
               * Type:String 
               * Class Name:MyClass 
               * Attribute Name:CONSTANT
               
          */

              pointcut getConstantPointcut():get(
          public static final String MyClass.CONSTANT);
              
              
          //Advice declaration
              before():getConstantPointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by getConstantPointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }

           

          二. 捕獲訪問的字段值
              使用after returning(<ReturnValue>)形式的通知。它在聲明的returning()部分中帶有一個標識符,用于包含訪問過的值。

          package com.aspectj;

          public aspect CaptureAccessedFieldValue {
              pointcut getNamePointcut() : get(String MyClass.name);
              
              
          //Advice declaration
              after() returning(String value) : getNamePointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by getNamePointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }


          三. 捕獲何時修改對象的字段
              使用set(Signature)切入點。set(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : set(<optional modifier> <type> <class>.<field>);
              
              set(Signature)具有4個關鍵特征:
              1.set(Signature)切入點在修改字段時觸發。
              2.set(Signature)切入點不能捕獲對靜態字段的修改,盡管從AspectJ的語法角度講以這種方式定義切入點是完全合法的。
              3.Signature必須解析成特定類的屬性。
              4.Signature可以包含通配符,用于選擇不同屬性上的一系列連接點。

          package com.aspectj;

          public aspect SetRecipe {
              
          /*
               * Specifies calling advice whenever an attribute
               * matching the following rules is modified:
               * 
               * Type: String
               * Class Name: MyClass
               * Attribute: name
               
          */

              pointcut setNamePointcut() :set(String MyClass.name);
              
              
          //Advice declaration
              before():setNamePointcut() && !within(SetRecipe+{
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by setNamePointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }

           

          四. 在修改字段時捕獲它的值
              結合使用args([Types | Identifiers])切入點和set(Signature)切入點,展示字段的新值,該字段被設置成切入點上的標識符,可將其傳遞給相應的通知。

          package com.aspectj;

          public aspect CaptureModifiedFieldValue {
              pointcut setNamePointcut(String newValue):set(String MyClass.name) 
          && args(newValue);
              
              
          //Advice declaration
              before(String newValue) : setNamePointcut(newValue) {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by setNamePointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");                
              }

          }

          posted @ 2008-08-22 10:43 Brian 閱讀(1183) | 評論 (0)編輯 收藏

          一.  捕獲對構造函數的調用
              使用Call(Signature)寫入點,它帶有額外的new關鍵字作為簽名的一部分。使用與構造函數有關的call(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>): call(<optional modifier> <class>.new(<parameter types>));

              在用于捕獲對構造函數的調用時,call(Signature)切入點具有3個關鍵特征:
              1.在把一個類實例化成一個對象時,具有new關鍵字的call(Signature)切入點會捕獲連接點。
              2.通過使用around()形式的通知,call(Signature)寫入點可以在Java的正常繼承規則的限制下重寫返回對象的類型。
              3.編譯器不會檢查指定的Signature是否對應于實際的構造函數。

           

          package com.aspectj;

          public aspect CallNewRecipe {
              
          /*
               * Specifies calling advice when any constructor is called
               * that meets the following signature rules:
               * 
               * Class Name:MyClass
               * Method Name:new (This is a keyword indicating the constructor call)
               * Method Parameters: int , String
               
          */

              pointcut myClassConstructorWithIntAndStringPointcut() : call(MyClass.
          new(int , String));
              
              
          //Advice declaration
              before() : myClassConstructorWithIntAndStringPointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by myClassConstructorWithIntAndOthersPointcut()");
                  System.out.println(
          "The current type of object under construction is:");
                  System.out.println(thisJoinPoint.getThis());
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");
              }

          }



          二. 在執行構造函數時捕獲它
              使用execution(Signature)切入點,它帶有額外的new關鍵字作為簽名的一部分。使用與構造函數有關的execution(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>):execution(<optional modifier> <class>.new<parameter types>));

              在用于捕獲構造函數的執行時,execution(Signature)切入點具有3個關鍵特征:
              1.在執行類的構造函數時,具有new關鍵字的execution(Signature)切入點會觸發連接點。
              2.不能在調用類的構造函數之前那一刻觸發連接點。這會阻止重寫返回的對象。
              3.可以使用around()通知來重寫構造函數方法的實現,當不能重寫正在構造的對象的類型。


          package com.aspectj;

          public aspect ExecutionNewRecipe {
              
          /*
               * Specifies calling advice when any constructor executes
               * that meets the following signature rules:
               * 
               * Class Name:MyClass
               * Method Name:new (This is a keyword indicating the constructor call)
               * Method Parameters: int , String
               
          */

              pointcut myClassConstructorWithIntAndStringPointcut() : execution(MyClass.
          new(int,String));
              
              
          //Advice declaration
              before() : myClassConstructorWithIntAndStringPointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by myClassConstructorWithIntAndOthersPointcut()");
                  System.out.println(
          "The current type of object under construction is:");
                  System.out.println(thisJoinPoint.getThis().getClass());
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }


          三. 捕獲何時初始化對象
              使用initialization(Signature)切入點。initialization(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>):initialization(<optional modifier> <class>.new<parameter types>));

              initialization(Signature)切入點具有5個關鍵特征:
              1.initialization(Signature)切入點必須包含new關鍵字。
              2.initialization(Signature)切入點捕獲連接點發生在任何超類的初始化之后,以及從構造函數方法返回之前。
              3.Signature必須解析成特定類的構造函數,而不是一個簡單的方法。
              4.initialization(Signature)切入點提供了編譯時的檢查,用于檢查構造函數是否正在被引用。
              5.由于AspectJ編譯器中的編譯器限制,當與around()通知關聯時,不能使用initialization(Signature)切入點。

           

          package com.aspectj;


          public aspect InitializationRecipe {
              
          /*
               * Specifies calling advice when any object
               * initializes using a constructor
               * that meets the following signature rules:
               * 
               * Class Name:MyClass
               * Method Name:new (This is a keyword indicating the constructor call)
               * Method Parameters: int and any others
               
          */

              pointcut myClassObjectInitializationWithIntAndStringPointcut() : execution(MyClass.
          new(int,*));
              
              
          //Advice declaration
              before() : myClassObjectInitializationWithIntAndStringPointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by myClassObjectInitializationWithIntAndStringPointcut()");
                  System.out.println(
          "The current type of object under construction is:");
                  System.out.println(thisJoinPoint.getThis().getClass());
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }



          四. 捕獲何時將要初始化一個對象
              使用preinitialization(Signature)切入點。preinitialization(Signature)切入點的語法如下:
              pointcut <pointcut name>(<any values to be picked up>):preinitialization(<optional modifier> <class>.new<parameter types>));

              preinitialization(Signature)切入點具有5個關鍵特征:
              1.preinitialization(Signature)切入點必須包含new關鍵字。
              2.preinitialization(Signature)切入點捕獲連接點發生在進入捕獲構造函數之后,以及調用任何超類構造函數之前。
              3.Signature必須解析成一個構造函數。
              4.preinitialization(Signature)切入點提供了編譯時的檢查,用于檢查構造函數是否正在被引用。
              5.由于AspectJ編譯器中的編譯器限制,當與around()通知關聯時,不能使用preinitialization(Signature)切入點。

           

          package com.aspectj;

          public aspect PreInitializationRecipe {
              
          /*
               * Specifies calling advice just before an object initializes
               * using a constructor that meets the following signature rules:
               * 
               * Class Name:MyClass
               * Method Name:new (This is a keyword indicating the constructor call)
               * Method Parameters: an int followed by a String
               
          */

              pointcut myClassIntStringObjectPreInitializationPointcut() : preinitialization(MyClass.
          new(int,String));
              
              
          //Advice declaration
              before(int number , String name) : myClassIntStringObjectPreInitializationPointcut() && args(number , name) {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by anyMyClassObjectInitializationPointcut()");
                  System.out.println(
          "The current type of object under construction is:");
                  System.out.println(thisJoinPoint.getThis());
                  System.out.println(
          "The values passed in where: " + number + " , " + name);
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }



          五. 捕獲何時初始化類
              使用staticinitialization(TypePattern)寫入點。staticinitialization(TypePattern)寫入點的語法如下:
              pointcut <pointcout name>(<any values to be picked up>) : staticinitialization(<class>);

              staticinitialization(TypePattern)切入點具有兩個關鍵特征:
              1.對可供staticinitialization(TypePattern)切入點所選通知使用的環境有一些限制。沒有父對象觸發靜態初始化;因此,沒有this引用。也不涉及實例對象,因此,沒有目標引用。
              2.TypePattern可以包含通配符,用于選擇一系列不同的類。

          package com.aspectj;

          public aspect StaticinitializationRecipe {
              
          /*
               * Specifies calling advice when a class is initialized
               * that meets the following type pattern rules:
               * 
               * Class Name:MyClass
               
          */

              pointcut myClassStaticInitializationPointcut() : staticinitialization(MyClass);
              
              
          //Advice declaration
              before() : myClassStaticInitializationPointcut() {
                  System.out.println(
          "---------- Aspect Advice Logic ----------");
                  System.out.println(
          "In the advice picked by myClassStaticInitializationPointcut()");
                  System.out.println(
          "Join Point Kind: ");
                  System.out.println(thisJoinPoint.getStaticPart().getKind());
                  System.out.println(
          "Signature: " + thisJoinPoint.getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getSourceLocation());
                  System.out.println(
          "-----------------------------------------");        
              }

          }

          posted @ 2008-08-22 10:32 Brian 閱讀(1237) | 評論 (0)編輯 收藏

              在Java中拋出異常時,會將其向上傳遞給調用者,直到它被作為try/catch塊一部分的catch語句處理或者到達Java運行庫并在控制臺引發一條混亂的消息。如果捕獲到異常,就應該將異常作為一個對象傳遞給catch塊做合適的處理。同時,還有一種可能需要方面作為橫切行為做一部分事情,或者替代catch塊的正常行為。
          一. 捕獲何時捕捉異常
              使用handler(TypePattern)切入點。其語法如下:
              pointcut <pointcut name>(<any values to be picked up>) : handler(<class>):
           
             handler(TypePattern)切入點具有5個關鍵特征:
             1. handler(TypePattern)在捕獲異常的作用域內選擇連接點。
             2. handler(TypePattern)切入點的通知僅用于類型模式指定Throwable或其子類的地方。
             3. TypePattern聲明無論何時捕捉到異常或其子類的匹配模式,都會應用相應的通知。
             4. handler(TypePattern)切入點只支持before()形式的通知。這意味著不能使用像around()這樣的通知來重寫catch塊的正常行為。
             5. TypePattern可以包含通配符,用于選擇不同類上的一系列連接點。
          帶有通配符的TypePattern 描述
          mypackage..* 捕獲mypackage包及其子包中的連接點類
          MyClass+ 捕獲MyClass類及其任何子類中的連接點

              下面的例子展示了捕獲任何類拋出MyException類異常:

          package com.aspectj;

          public aspect HandlerRecipe {
              
          /**
               * Specifies calling advice when any exception object
               * is caught that matches the following rules for its 
               * type pattern;
               * 
               * Type:MyException
               
          */

              pointcut myExceptionHandlerPointcut() : handler(MyException);
              
              
          //Advice declaration
              before() : myExceptionHandlerPointcut() {
                  System.out.println(
          "------------------- Aspect Advice Logic -------------------");
                  System.out.println(
          "In the advice picked by " + "myExceptionHandlerPointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "------------------------------------------");
              }

          }


          二. 捕獲拋出的異常
              結合使用args([Types | Identifiers])切入點 與handler(TypePattern)切入點,將捕獲的異常展示為切入點上的標識符,可將其傳遞給相應的通知。
          package com.aspectj;

          public aspect AccessThrownException {
              pointcut myExceptionHandlerPointout(MyException exception) : handler(MyException) 
          && args(exception);
              
              
          //Advice declaration
              before(MyException exception) : myExceptionHandlerPointout(exception) {
                  System.out.println(
          "------------------- Aspect Advice Logic -------------------");
                  System.out.println(
          "In the advice picked by " + "myExceptionHandlerPointcut()");
                  System.out.println(
          "Signature: " + thisJoinPoint.getStaticPart().getSignature());
                  System.out.println(
          "Source Line: " + thisJoinPoint.getStaticPart().getSourceLocation());
                  System.out.println(
          "Exception caught:");
                  exception.printStackTrace();
                  System.out.println(
          "------------------------------------------");
              }

          }
             
          posted @ 2008-07-11 09:28 Brian 閱讀(1613) | 評論 (1)編輯 收藏
          僅列出標題
          共5頁: 上一頁 1 2 3 4 5 下一頁 

          公告


          導航

          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          統計

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 昭觉县| 泗阳县| 祁连县| 昌黎县| 汝城县| 蓝山县| 德江县| 二手房| 霍州市| 澎湖县| 廊坊市| 合作市| 赤水市| 铜陵市| 包头市| 瓮安县| 惠水县| 扎赉特旗| 普定县| 朝阳市| 晋江市| 西充县| 昆山市| 兴业县| 磴口县| 朝阳市| 当阳市| 云林县| 长海县| 平度市| 汕尾市| 乃东县| 尚义县| 怀仁县| 湟源县| 应城市| 红原县| 郸城县| 乐陵市| 松溪县| 页游|