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相当于Preinitialization,而Execution相当于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()也会触发。