pointcut语言是允许joinpoint匹配的工具。pointcut表达式定义了joinpoint应该在哪个地方执行。
1) *是常规的通配符,它匹配0或多个字符,可以用于任何类型表达式,field,方法名称,但是不能在annotation表达式中。
2) ..用于在构造器或方法表达式中指定任意多个参数。..紧跟在包名之后,用来指定匹配在给定包名内的所有类,但是不包括sub-package内的类。例如org.acme..匹配org.acme.Foo和org.acme.Bar,但是不匹配org.acme.sub.SubFoo。
1)org.acme.SomeClass匹配该类
2)org.acme.*匹配org.acme.SomeClass,也匹配org.acme.SomeClass.SomeInnerClass
3)@javax.ejb.Entity将匹配任何被该annotation标记的类。
4)必须指定每个java类的全名。
为了引用每个类的所有子类,可以使用$instanceof{}表达式。
annotation可以用来替代Class名称。下例匹配被@javax.ejb.Entity类的任何方法。
wildcards
在pointcut表达式中有两种通配符类型可以使用。1) *是常规的通配符,它匹配0或多个字符,可以用于任何类型表达式,field,方法名称,但是不能在annotation表达式中。
2) ..用于在构造器或方法表达式中指定任意多个参数。..紧跟在包名之后,用来指定匹配在给定包名内的所有类,但是不包括sub-package内的类。例如org.acme..匹配org.acme.Foo和org.acme.Bar,但是不匹配org.acme.sub.SubFoo。
Type Patterns
Type pattern被annotation或全名class名称定义。Annotation表达式不允许有通配符,但是类表达式有。1)org.acme.SomeClass匹配该类
2)org.acme.*匹配org.acme.SomeClass,也匹配org.acme.SomeClass.SomeInnerClass
3)@javax.ejb.Entity将匹配任何被该annotation标记的类。
4)必须指定每个java类的全名。
为了引用每个类的所有子类,可以使用$instanceof{}表达式。
$instanceof{org.acme.SomeInterface}
$instanceof{@org.acme.SomeAnnotation}
$instanceof{org.acme.interfaces.*}
对于更复杂的类型表达式,可以使用Typedef。
$typedef{id}
Method Patterns
public void org.acme.SomeClass->methodName(java.lang.String)
方法的属性(public,static,private)是可选的,如果属性缺省,任何属性都会被假定。属性能接受!修饰符作为否定。 public !static void org.acme.SomeClass->*(..)
$instanceof{}可以用来取代类名。 void $instanceof{org.acme.SomeInterface}->methodName(java.lang.String)
挑选包org.acme中所有类的toString()方法: java.lang.String org.acme..->toString()
匹配给定接口方法使用$implements{}或$implementing{}替换方法名称。annotation可以用来替代Class名称。下例匹配被@javax.ejb.Entity类的任何方法。
void @javax.ejb.Entity->methodName(java.lang.String)
annotation可以被用来替换方法名称,必须标记为@javax.ejb.Tx* *->@javax.ejb.Tx(..)
此外,可以使用typedefs,$instanceof{},annotation和通配符来匹配方法参数和返回类型。下例
@javax.ejb.Entity *->loadEntity($instanceof{@org.acme.Ann},java.*.String)
匹配方法:返回类型标为@javax.ejb.Entity,接收参数为标记为@org.acme.Ann和匹配java.*.String。public void org.acme.SomeClass->methodName(java.lang.String)throws org.acme.SomeException, java.lang.Exception
如果任何异常出现在pointcut表达式中,他们必须春现在匹配的方法中。Constructor Patterns
构造器表达式有类的全名和new关键词,属性构成。如果属性缺失,将使用假定值。public org.acme.SomeClass->new(java.lang.String)
!public org.acme.SomeClass->new(..)//属性接收!修饰符。
$instanceof{org.acme.SomeInterface}->new(..)//$instanceof{}用于className
org.acme..->new()//挑选包org.acme内的所有无参构造器的类。
@javax.ejb.Entity->new(..)//挑选标记为@javax.ejb.Entity类的构造器
*->@javax.ejb.MethodPermission(..)//替换new关键词,匹配被标记为@javax.ejb.MethodPermission的构造器
*->new(@org.acme.Ann, java.*.String)//标记和通配符来替代参数
public void org.acme.SomeClass->new(java.lang.String) throws org.acme.SomeException, java.lang.Exception//可以包含异常
Field Patterns
field表达式类似构造器表达式,由type,类全名和field名构成。属性(public static private)是可选的,如果没有使用属性,则使用假定的属性,属性接收!修饰符。public java.lang.String org.acme.SomeClass->fieldname//标准表达式
!public java.lang.String org.acme.SomeClass->*//否定修饰符
* $instanceof{org.acme.SomeInterface}->*//使用$instanceof替换类
* @javax.ejb.Entity->*//使用@javax.ejb.Entity替换类,凡是被标记的类都将被匹配到
* *->@org.jboss.Injected//@org.jboss.Injected替换field名
除此之外,可以使用typedef,$instanceof{},annotation和通配符来修饰field类型。例如
@javax.ejb.Entity *->*
Pointcuts
Pointcuts使用class,field,constructor和method表达式来指定需要拦截或监测的实际的joinpointexecution(method or constructor)//拦截方法或构造器
execution(public void Foo->method()
execution(public Foo->new())
/**指定aspect在构造器内执行
execution要求调用new()的代码必须被编译器拦截。construction则要求aspects被植入在构造器所有代码后
*/
construction(constructor)
construction(public Foo->new())
/**get指定当field被读操作访问时,被拦截器*/
get (field expression)
get(public int Foo->fieldname)
/**set指定当field被写操作访问时,被拦截器*/
set(field expression)
set(public int Foo->fieldname)
/**field指定当field被读或写操作访问时,被拦截器*/
field(field expression)
field(public int Foo->fieldname)
/**指定某个类的任何构造器、方法、field被拦截,如果使用annotation,则匹配成员的annotation*/
all(type expression)
all(org.acme.SomeClass)
all(@org.jboss.security.Permission)
/**call用来指定拦截的任何构造器或方法,它不同与execution,它发生在调用者这边,且调用者信息对Invocation来说可见*/
call(method or constructor)
call(public void Foo->method()
call(public Foo->new())
/**within匹配任何在特定类型代码之内的joinpoint(method或constructor调用)*/
within(type expression)
within(org.acme.SomeClass)
within(@org.jboss.security.Permission)
/**withincode匹配特定method或constructor内的任何joinpoint**/
withincode(method or constructor)
withincode(public void Foo->method()
withincode(public Foo->new())
/**has是匹配的额外要求,如果joinpoint匹配到了,它的class必须有一个constructor或method满足has表达式*/
has(method or constructor)
has(void *->@org.jboss.security.Permission(..))
has(*->new(java.lang.String))
/**如果joinpoint被匹配,它的class必须有一个constructor或method满足hasfield表达式**/
hasfield(field expression)
hasfield(* *->@org.jboss.security.Permission)
hasfield(public java.lang.String *->*)
Pointcut Composition
pointcut可以是组合成布尔表达式:!(逻辑否)and(逻辑与) or(逻辑或),和(),用来分组call(void Foo->someMethod()) AND withincode(void Bar->caller())
execution(* *->@SomeAnnotation(..)) OR field(* *->@SomeAnnotation)