第八章 Advice顺序
8.1 Aspect的优先级
Aspect C++为定义aspect的优先级提供了非常弹性化的机制。如果有多个aspect影响同一个join point,则由优先级决定advice代码执行的顺序。Aspect C++中,优先级是join point的一个属性。也就是说,两个aspect的优先级关系在系统不同的部分会有区别。编译器检查下面的条件,以决定aspect的优先级:
顺序的声明:如果程序员给出了顺序声明,那么编译器会遵循该声明,如果编译器发现优先级图中存在回路,那么编译器会提示编译器错误并中止。顺序的声明语法如下:
advice pointcut-expr : order( high, …low )
order的参数列表中至少要包含两个元素。每个元素是一个pointcut表达式,描述了一个aspect。左边的优先级高于右边的。例如,一位了A1的优先级高于A3、A4,A2的优先级也高于A3、A4。这个例子中没有定义A1和A2之间的优先关系,也没有给出A3、A4的优先关系。当然,参数列表中的pointcut表达式也可以包含命名的pointcut,甚至是纯虚pointcut。
继承关系:如果没有给出顺序的声明,并且一个aspect有基类aspect,那么派生类aspect的优先级高于基类aspect。
8.2 Advice的优先级
davice的优先级通过非常简单的机制来决定:
l 如果两个advice来自不同的aspect,并且这两个aspect之间存在优先级关系,那么advice的优先级关系和aspect的相同;
l 如果两个advice来自同一个aspect,那么先声明的advice的优先级高于后声明的。
8.3 Advice优先级的影响
只有advice优先级对生成的代码有影响。此影响依赖于join point的类型.
Class Join Point
作用在class join point上的advice可以扩展属性列表或基类列表。如果一个advice比另一个advice的优先级高,那么就会先处理这个advice。例如,如果一个用于引入新基类的advice具有高优先级,那么在基类列表中,他引入的基类就会出现在低优先级advice引入的基类的左边。也就是说,基类的执行顺序会被影响。
引入属性的顺序也会影响构造函数和析构函数的执行顺序以及对象的布局。
Code Join Point
code join point上的advice可以是before, after,aroun的advice。对于before和around的advice而言,优先级越高意味着相应的advice代码会越早先运行。对after的advice而言,优先级越高意味着advice代码会越迟运行。
如果around的advice代码中不调用tjp->proceed()或不在action代码上调用trigger(),那么低优先级的advice代码就不会运行。低优先级的around advice不会影响高优先级的advice的执行。
例如,考虑下面这个aspect,它按下面的顺序定义了advice:BE1, AF1, AF2, AR1, BE2, AR2, AF3。如8.2节所述,定义顺序决定了优先级:BE1的优先级最高,AF3优先级最低。下面是advice代码的执行顺序:
1. BE1(优先级最高);
2. AR1((a) (b)中的advice只有在proceed()被调用时才会执行);
(a) BE2(在AR2之前执行,但BE2的执行依赖于AR1,如果AR2中不调用proceed(),那么就不会执行BE2);
(b) AR2(i和ii的代码只有在AR2中调用了proceed()才会执行)
i. join point的原始代码;
ii. AF3;
3. AF2(不依赖于AR1、AR2,因为AF2的优先级更高);
4. AF1(在AF2之后运行,因为AF1的优先级比AF2高)。
至此,对pure system《AspectC++ Language Reference》的翻译结束。接下俩会找点文章看看AspectC++的应用实例。