/* 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)
呢?
答案 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
参数,我需要在切入点中使用它,并且需要绑定到切入点定义中的某些内容。