关于AspectJ 中的pointcut 语法

    技术2024-07-28  58

    pointcut,从字面的意思说的是切面的意思。也就是横切的时候,会有哪些执行点会被识别。只有先识别了,才能执行相应的Advice。

    基本的定义如下:

     

    public pointcut accountOperations:call(* Account.*(..))

     

    1.通配符和pointcut 操作符 

     

    * 表示任何数量的字符,除了(.) 

    .. 表示任何数量的字符包括任何数量的(.) 

    + 描述指定类型的任何子类或者子接口

    同java一样,提供了一元和二元的条件表达操作符。

    一元操作符:!

    二元操作符:||和&&

    优先权同java

     

    2.签名语法 

     

    类型签名样式 

     

    主要的例子:

    Account 类型Account

    *Account 使用Account名称结束的类型,如SavingsAccount和CheckingAccount

    java.*.Date 类型Date在任何直接的java子包中,如java.util.Date和java.sql.Date

    java..* 任何在java包或者所有子包中的类型,如java.awt和java.util或者java.awt.event 和java.util.logging

    javax..*Model+ 所有javax包或者子包中以Model结尾的类型和其所有子类,如TableModel,TreeModel。

    !vector 所有除了Vector的类型

    Vector|| Hashtable Vector或者Hashtable类型

    java.util.RandomAccess+ 实现RandomAccess和List的所有子类

    && java.util.List+

     

    方法和构造器签名模式 

     

    public void Collection.clear():

    在Collection中同样签名的clear方法

     

    public void Account.debit(float) throws InsufficientBalanceException:

    Account中同样签名的debit方法

     

    public void Account.set*(*)

    Account中以set开头,并且只有一个参数类型的方法

     

    public void Account.*()

    Account中所有的没有参数的public void 方法

     

    public * Account.*()

    Account中所有没有参数的public 方法

     

    public * Account.*(..)

    Account中所有的public 方法

     

    * Account.*(..)

    Account中的所有方法,包括private方法

     

    !public * Account.*(..)

    所有的非public 方法

     

    * Account+.*(..)

    所有的方法,包括子类的方法

     

    * java.io.Reader.read(..)

    所有的read方法

     

    * java.io.Reader.read(char[],..)

    所有以read(char[])开始的方法,包括read(char[])和read(char[],int,int)

     

    * javax..*.add*Listener(EventListener+)

    命名以add开始,以Listener结尾的方法,参数中为EventListener或子类

     

    * *.*(..) throws RemoteException

    抛出RemoteException的所有方法

     

    构造器,同上面

    public Account.new()

    没有参数的构造器方法

     

    属性签名模式 

    同方法一样,属性也查不多

    * Account.* 

    所有的Account属性

     

    !public static * banking..*.*

    所有的非public static 属性,在banking的包或者子包中

     

    3.主要的pointcuts类型 

     

    分类pointcuts

    遵循特定的语法用于捕获每一个种类的可使用连接点。

    主要的种类:

     

    方法执行:execution(MethodSignature) 

    方法调用:call(MethodSignature) 

    构造器执行:execution(ConstructorSignature) 

    构造器调用:call(ConstructorSignature) 

    类初始化:staticinitialization(TypeSignature) 

    属性读操作:get(FieldSignature) 

    属性写操作:set(FieldSignature) 

    例外处理执行:handler(TypeSignature) 

    对象初始化:initialization(ConstructorSignature) 

    对象预先初始化:preinitialization(ConstructorSignature) 

    Advice执行:adviceexecution()

    基于控制流的pointcuts

    主要包括两种类型的控制流:

    cflow(Pointcut),捕获所有的连接点在指定的方法执行中,包括执行方法本身。

    cflowbelow(Pointcut),捕获所有的连接点在指定的方法执行中,除了执行方法本身。

     

    如以下的例子:

    cflow(call(* Account.debit(..))

    所有的debit方法中的连接点,包括debit方法本身

    cflowbelow(call(* Account.debit(..))

    所有debit方法中的连接点,除了debit方法本身

    cflow(transactedOperations())

    所有由transactedOperations捕获的连接点

    cflowbelow(execution(Account.new(..))

    所有在Account 构造器中执行的连接点

     

    基于词汇结构的连接点

    源代码片断。,如within()和withincode()

    within :捕获在指定类或者方面中的程序体中的所有连接点,包括内部类。

    Withincode:用于捕获在构造器或者方法中的所有连接点,包括在其中的本地类

     

    执行对象连接点

    匹配this,和target对象,作为方法被调用的对象。

    this(Account),所有Account的实例的执行点,匹配所有的连接点,如方法调用,属性设置,当前的执行对象为Account,或者其子类。

    target(Account):匹配所有的连接点,目标对象为Account或其子类。

     

    必须执行相应的类型,不能使用*,或者..通配符。当前静态方法,不能被匹配。

     

    在within()和this()中的区别:

    一个是程序体,而另一个为对象执行。

     

    参数pointcuts

    用于捕获参数类型的连接点。

    args(String,..,int)

    args(RemoteException)

     

    条件检测pointcuts

    if(System.currentTimeMillis()>triggerTime)

     

    AspectJ5 已经增加了不少语法,主要关于Annotation 的

    最新回复(0)