2.5 运行时支持

2016-03-27  本文已影响59人  liril

2.5 运行时支持

2.5.1 建议代码支持

对于许多方向来说,访问上下文变量并不能获得关于建议代码激活的结合点的足够信息。例如,对于一个函数调用完整的日志控制流方向,我们需要关于函数参数和运行时类型的相关信息,这样才可能产生类型匹配的输出。

在AspectC++中,这一信息由类JoinPoint的成员提供(见下表)。

表 1:建议代码中可用的类JoinPoint的API

JoinPointAPI的类和静态方法对每个建议代码激活是传递的信息都是相同的。而非静态方法在不同的激活里传递的信息是不同的。这些方法可以通过对象tjp分别访问。JoinPoint类型的thisJoinPoint也一直可以在建议代码中访问到。

下面的例子演示了如何使用JoinPointAPI实现一个可复用的控制流方向。

例:可复用追踪方向

aspect Trace {
    pointcut virtual methods() = 0;

    advice execution(methods()) : around() {
        cout << "before " << JoinPoint::signature() << "(";
        for (unsigned i = 0; i < JoinPoint::args(); i++) {
            printvalue(tjp->arg(i), JoinPoint::argtype(i));
        }
        cout << ")" << endl;
        tjp->proceed();
        cout << "after" << endl;
    }
};

这个对象通过重新定义派生方向指定的虚点切将追踪代码编织到每个函数中。帮助者函数printvalue负责格式化输出函数调用中给出的参数。在为每个参数调用printvalue之后,实际结合点的程序代码通过调用JoinPoint对象的proceed执行。proceed的功能通过使用这样的动作实现。

2.5.2 动作

在AspectC++中,动作是在运行的程序到达的结合点后建议代码不会激活后跟随的状态序列。因此tjp->proceed()触发了结合点的程序代码的执行。这款也是函数的调用或者执行。动作概念可以在AC::Action结构中查询到。事实上,proceed等同于action().trigger(),所以tjp->proceed()也可以使用tjp->Action().trigger()替代。因此JoinPointAPI的action()方法实际上返回了结合点的真正的动作对象。

上一篇下一篇

猜你喜欢

热点阅读