阅读和理解AspectJ切入点?

时间:2015-03-10 16:41:09

标签: java aspectj pointcut pointcuts

/* 0 */ pointcut services(Server s): target(s) && call(public * *(..))
     

这个名为服务的切入点在执行中挑选出这些点   Server对象调用其公共方法时的程序。   它还允许使用服务切入点的任何人访问服务器   正在调用其方法的对象。   (取自https://eclipse.org/aspectj/doc/released/progguide/language-anatomy.html

我试图了解AspectJ的切入点,目前我感到非常困惑。我的主要问题是:你如何阅读上述切入点,以及你如何解读?它的意思在一起?

为了说明我的困惑,让我们尝试从头开始构建:

以下切入点会拦截对任何对象的所有公共方法调用,对吗?

/* 1 */ pointcut services() : call(public * *(..))

现在,这个怎么样:

/* 2 */ pointcut services() : call(public * Server.*(..)) 

我认为在调用Server对象的公共方法时会拦截任何点。

现在,我如何从这里得到最初的例子0?我该如何阅读?

在构建切入点时,您是否首先提供参数列表?

/* 3a */ pointcut services(Server s) : call(public * *(..))

与上面的数字2相同吗? (我觉得它不会起作用,如果确实如此,它会拦截"每个公共方法调用,就像数字1一样。)无论如何,以下是否会相同? (我不是"用原生切入点捕获" s,所以我无法真正定义它,是吗?)

/* 4a */ pointcut services(Server /* only type, no variable */) : call(public * *(..))

或者你会从指定原生切入点开始,到#34;捕获"目标对象,如下所示:

/* 3b */ pointcut services() : target(s) && call(public * *(..))

我想这仍会拦截任何对象上的所有公共方法调用?

以下工作只会拦截Server对象上的调用,以及" capture"那个对象(没有让它可以在以后传递,例如建议)?

/* 5 */ pointcut services(/*nothing here*/) : target(s) && call(public * Server.*(..))

现在,回到原来的切入点:

/* 0 */ pointcut services(Server s): target(s) && call(public * *(..))

相同
/* 6 */ pointcut services(Server s): target(s) && call(public * Server.*(..))

所以,总结一下: 你如何开始破译0?

你首先看target切入点,然后是services切入点的参数类型并阅读它"从里到外" /"从右到左& #34 ;? 或者您首先查看参数列表,然后查看services切入点以查看参数的来源(即target(s))?

或者我这太复杂了?我错过了一个重要的地方来帮助我理解这个吗?

编辑:手册从左到右解释 - 但如果我没有执行"参数Server s的参数来自何处? target(s)呢?

1 个答案:

答案 0 :(得分:4)

1:是的,它拦截任何公共方法调用。

2:它拦截对象声明的任何公共方法调用为Server,而0拦截对象的任何公共调用,该对象是Server的实例。请参阅the semantics

3a:由于s未绑定,因此无法编译:

[ERROR] formal unbound in pointcut
        .../src/main/aspect/MyAspect.aj:18
pointcut services(Server s): call(public * *(..));

4a:语法无效,就像在界面中声明方法时需要命名参数一样:

[ERROR] Syntax error, insert "... VariableDeclaratorId" to complete FormalParameterList
        .../src/main/aspect/MyAspect.aj:18
pointcut services(Server): call(public * *(..));
                  ^

3b:它无效,s尚未宣布:

[WARNING] no match for this type name: s [Xlint:invalidAbsoluteTypeName]
        .../src/main/aspect/MyAspect.aj:18
pointcut services(): target(s) && call(public * *(..));

5:与3b一样,s尚未宣布。

6:它与0不同,它只匹配公共 Server 方法调用(即在Server中声明)到{{1}实例。

我在a Github repository中说明了不同的情况:在分支之间切换以尝试它们。在aspect7分支中有一个额外的案例,基于6,我在Server覆盖hashCode()

你可以(并且应该)尝试自己,以便更好地理解。


为了回答你的最后一个问题,切入点的论点来自于我们希望(能够)通过将其作为参数提供给建议来访问建议中的调用目标。建议的签名需要包含所有引用切入点的参数,切入点参数需要引用建议中的参数。

因此,要在建议中使用Server参数,我需要在切入点中使用它,并且需要绑定到切入点定义中的某些内容。