当前位置: 首页 > 工具软件 > JBoss AOP > 使用案例 >

JBoss AOP之Joinpoint和Pointcut表达式

子车征
2023-12-01
    pointcut语言是允许joinpoint匹配的工具。pointcut表达式定义了joinpoint应该在哪个地方执行。

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表达式来指定需要拦截或监测的实际的joinpoint
    
execution(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)







 类似资料: