一:一个典型的aspect类的形式如下:
public aspect MyAspectj { //定义连接点函数 pointcut callF(): execution(* f(..)) && cflow(call(* Test.foo(..))); //定义通知函数 before() : callF() { System.out.println("before call f();"); } }
二:切点pointcut的定义:
1):方法的访问
1: execution():表示方法执行是进行匹配,如下所示:
execution(void Test.setX(int,**))
2: call():表示在方法被调用时候进行匹配,如下所示:
call(void Test.setX(int,**))
2):字段的访问:
1: set():表示目标对象的修改,如下所示:
before(int newval): set(int Test.x) && args(newval) {
if(newval > Test.MAX_CHANGE) {
throw new RuntimeException("error");
}
}
public static final int MAX_CHANGE = 100;
int x = 100;
public static void main(String[] args) {
Test t = new Test();
t.x = 10000;
System.out.println(t.x);
}
2:get():表示目标对象的获取,如下所示:
before(): get(int Test.x)
3):对象的状态:
1:this(SomeType):表示当前在执行的对象是SomeType类型进行匹配。
2:target(SomeType):表示目标对象是SomeType类型时进行匹配。
3:args(SomeType):表示目标函数的函数参数是SomeType类型时进行匹配。
4):连接点执行流程
1:cflow(pointcut):表示在执行连接点pointcut所匹配的函数时进行匹配,如下所示:
cflow(call(void Test.main()))
其中的call(void Test.main())就是一个连接点;
2:cflowbelow(pointcut):表示执行连接点pointcut之外所匹配的函数是进行匹配,如下所示。
cflow(call(void Test.main()))
5):属于关系
1:within(MyClass)表示当前正在执行的代码属于MyClass类时进行匹配(连接点匹配的时候只匹配Myclass类中的连接点),如下所示:
within(point)
2:withincode(method):表示在属于method函数时进行匹配,例如夏例表示的时匹配函数foo()的调用。
withincode(public void foo())
三:匹配表达式的通配符
使用星号"*"可以匹配切点中函数表达式中的任何一个元素,包括函数的修饰符,返回值的类型,类名,方法名,参数名。
1)星号(*)
1:下例将匹配任何函数,而不管函数返回什么的类型。
execution(* *(..))
2:下例用来匹配任何名为set的方法,而不管函数返回的类型。
call(* set(..))
3:下例用于匹配返回值为int型的任何函数。
execution(int *(..))
4:下例用来匹配函数名为setY,参数类型为long的函数。
call(* setY(long))
5:下例用于匹配类Point的函数setY,且函数的参数类型为int。
call(* Point.setY(int))
6:下例用来匹配任意的构造函数,且该构造函数含有两个int类型的参数。
call(*.new(int,int))
7:下例用来匹配任何public类型的函数。
call(public * *(..))
8 : 下例用来匹配任何非静态的函数。
execution(!static * *(..))
9:下例用来匹配任何public类型的,非静态的函数
execution(public !static * *(..))
2):加号(+)
1:匹配Foo的构造函数
call(Foo.new())
2:下例表示Foo及其所有子类的构造函数。
call(Foo+.new())
3:下例以Handler结尾的类名及其所有子类的构造函数。
call(*Handler+.new())
四:匹配表达式的组合
!:逻辑非;
|| or OR:逻辑或;
&& or And:逻辑与;
():用于分钟。
一些切点的实例: