aspectJ的this和target的區別;execution與call在使用ajc編譯與LTW之間的神坑

this和target區別:

this(Point)所有與Point執行過程中,出現調用點(包括它內部調用別人的方法)都會執行該切入的方法。

target(Point)只針對於與Point有關係的切入點(內部調用別人的不會)。

 

驗證舉例:

this類型的切面:

public aspect HellowAj {
after():this(aspectj.com.source.Hellow2){
    System.out.println(thisJoinPoint.getSignature().toString()+"執行了全匹配的切入"+thisJoinPoint.getKind());
}
}

裝飾對象:

public class Hellow2 {

    public void get(){

     int i=Math.max(1,0);
     System.out.println("值"+i);
    }
}

執行程序:

public class App 
{

    public static void main( String[] args ) {

        Hellow2 f=new Hellow2();
        f.get();
    }
}

 

結果:

aspectj.com.source.Hellow2()執行了全匹配的切入constructor-execution
aspectj.com.source.Hellow2()執行了全匹配的切入initialization
int java.lang.Math.max(int, int)執行了全匹配的切入method-call
PrintStream java.lang.System.out執行了全匹配的切入field-get
java.lang.StringBuilder(String)執行了全匹配的切入constructor-call
StringBuilder java.lang.StringBuilder.append(int)執行了全匹配的切入method-call
String java.lang.StringBuilder.toString()執行了全匹配的切入method-call
值1
void java.io.PrintStream.println(String)執行了全匹配的切入method-call
void aspectj.com.source.Hellow2.get()執行了全匹配的切入method-execution

==============================================

target類型

public aspect HellowAj {
after():this(aspectj.com.source.Hellow2){ System.out.println(thisJoinPoint.getSignature().toString()+"執行了全匹配的切入"+thisJoinPoint.getKind()); }
}

結果:

aspectj.com.source.Hellow2()執行了全匹配的切入constructor-execution
aspectj.com.source.Hellow2()執行了全匹配的切入initialization
int java.lang.Math.max(int, int)執行了全匹配的切入method-call
PrintStream java.lang.System.out執行了全匹配的切入field-get
java.lang.StringBuilder(String)執行了全匹配的切入constructor-call
StringBuilder java.lang.StringBuilder.append(int)執行了全匹配的切入method-call
String java.lang.StringBuilder.toString()執行了全匹配的切入method-call
值1
void java.io.PrintStream.println(String)執行了全匹配的切入method-call
void aspectj.com.source.Hellow2.get()執行了全匹配的切入method-execution

 

execution與call在使用ajc編譯與LTW之間的神坑:

call與execution在使用ajc編譯時,除非它修飾是構造方法(修飾構造方法時,Call相當於PreinitializationExecution相當於Initialization),否則它們倆沒有區別。

而在使用LTW方式時,則會有一個深坑,比如下面的例子:

切面定義:

@Aspect
public class AdviceOne {


    @Pointcut("execution(or call)(@*..MyMethod * (@*..My aspectj.com.source..*).*())")
    public void pointcut(){
    }

    @Before("pointcut()")
    public void before(){
        System.out.println("====this is before annotion=========");
    }



}

修飾方法

@My
public class BaseClass {

    public void toUse(){

        noUse();
    }


    @MyMethod
    public void  noUse(){

    }
}

用call修飾時,【在main方法裏】(前提條件,這是個坑),直接使用BaseClass.noUse則不會觸發call,使用toUse()會觸發。而使用Execution修飾noUse,使用BaseClass.noUse則直接觸發,使用toUse()也會觸發。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章