阅读和理解 AspectJ 切入点?
Reading and understanding AspectJ pointcuts?
/* 0 */ pointcut services(Server s): target(s) && call(public * *(..))
This pointcut, named services, picks out those points in the execution
of the program when Server objects have their public methods called.
It also allows anyone using the services pointcut to access the Server
object whose method is being called.
(taken from https://eclipse.org/aspectj/doc/released/progguide/language-anatomy.html)
我正在尝试理解 AspectJ 的切入点,但现在有点困惑。我的主要问题是:你如何阅读上面的切入点,你如何 "puzzle" 它的意思在一起?
为了说明我的困惑,让我们尝试从头开始构建:
下面的切入点会拦截对任何对象的所有 public 方法调用,对吗?
/* 1 */ pointcut services() : call(public * *(..))
现在,这个怎么样:
/* 2 */ pointcut services() : call(public * Server.*(..))
我假设在调用 Server 对象的 public 方法时会拦截任何点。
现在,如何从这里转到初始示例 0?我该如何阅读?
在构建切入点时,您是否会先提供参数列表?
/* 3a */ pointcut services(Server s) : call(public * *(..))
和上面的2一样吗? (我觉得它不会起作用,如果它起作用,它会在每次 public 方法调用时 "intercept" ,就像数字 1 一样。) 不管怎样,下面是一样的吗? (我还没有 "capturing" s
本地切入点,所以我不能真正定义它,可以吗?)
/* 4a */ pointcut services(Server /* only type, no variable */) : call(public * *(..))
或者您会先指定一个本机切入点,"capture" 目标对象,如下所示:
/* 3b */ pointcut services() : target(s) && call(public * *(..))
我想这仍然会拦截对任何对象的所有 public 方法调用?
以下工作是否仅拦截对服务器对象的调用,并"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
切入点的参数类型,再读"inside out"/"from right to left"?
还是先查看参数列表,然后查看 services
切入点以查看参数来自何处(即 target(s)
)?
还是我把它弄得太复杂了?我是否遗漏了重要的一点来帮助我理解这一点?
编辑: 手册从左到右对其进行了解释 - 但是如果我没有 "executed" Server s
参数的参数从何而来 target(s)
还没?
1:是的,它会拦截任何 public 方法调用。
2:它拦截对对象 声明为 的任何 public 方法调用作为 Server
,而 0 拦截任何 public 调用一个对象,它是 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不一样,它只匹配publicServer
方法调用(即在Server
中声明)到一个 Server
个实例。
我在 a Github repository 中说明了不同的情况:在分支之间切换以尝试它们。在 aspect7 分支中有一个额外的案例,基于 6,我在 Server
.
中覆盖 hashCode()
您可以(并且应该)自己尝试,以获得更好的理解。
为了回答你的最后一个问题,切入点的参数来自于这样一个事实,即我们希望(能够)通过将其作为参数提供给建议来访问建议中的调用目标。通知的签名需要包含所有引用的切入点的参数,切入点参数需要引用通知中的参数。
所以,要在建议中有一个 Server
参数,我需要在切入点中使用它,并且需要将它绑定到切入点定义中的某些内容。
/* 0 */ pointcut services(Server s): target(s) && call(public * *(..))
This pointcut, named services, picks out those points in the execution of the program when Server objects have their public methods called. It also allows anyone using the services pointcut to access the Server object whose method is being called. (taken from https://eclipse.org/aspectj/doc/released/progguide/language-anatomy.html)
我正在尝试理解 AspectJ 的切入点,但现在有点困惑。我的主要问题是:你如何阅读上面的切入点,你如何 "puzzle" 它的意思在一起?
为了说明我的困惑,让我们尝试从头开始构建:
下面的切入点会拦截对任何对象的所有 public 方法调用,对吗?
/* 1 */ pointcut services() : call(public * *(..))
现在,这个怎么样:
/* 2 */ pointcut services() : call(public * Server.*(..))
我假设在调用 Server 对象的 public 方法时会拦截任何点。
现在,如何从这里转到初始示例 0?我该如何阅读?
在构建切入点时,您是否会先提供参数列表?
/* 3a */ pointcut services(Server s) : call(public * *(..))
和上面的2一样吗? (我觉得它不会起作用,如果它起作用,它会在每次 public 方法调用时 "intercept" ,就像数字 1 一样。) 不管怎样,下面是一样的吗? (我还没有 "capturing" s
本地切入点,所以我不能真正定义它,可以吗?)
/* 4a */ pointcut services(Server /* only type, no variable */) : call(public * *(..))
或者您会先指定一个本机切入点,"capture" 目标对象,如下所示:
/* 3b */ pointcut services() : target(s) && call(public * *(..))
我想这仍然会拦截对任何对象的所有 public 方法调用?
以下工作是否仅拦截对服务器对象的调用,并"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
切入点的参数类型,再读"inside out"/"from right to left"?
还是先查看参数列表,然后查看 services
切入点以查看参数来自何处(即 target(s)
)?
还是我把它弄得太复杂了?我是否遗漏了重要的一点来帮助我理解这一点?
编辑: 手册从左到右对其进行了解释 - 但是如果我没有 "executed" Server s
参数的参数从何而来 target(s)
还没?
1:是的,它会拦截任何 public 方法调用。
2:它拦截对对象 声明为 的任何 public 方法调用作为 Server
,而 0 拦截任何 public 调用一个对象,它是 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不一样,它只匹配publicServer
方法调用(即在Server
中声明)到一个 Server
个实例。
我在 a Github repository 中说明了不同的情况:在分支之间切换以尝试它们。在 aspect7 分支中有一个额外的案例,基于 6,我在 Server
.
hashCode()
您可以(并且应该)自己尝试,以获得更好的理解。
为了回答你的最后一个问题,切入点的参数来自于这样一个事实,即我们希望(能够)通过将其作为参数提供给建议来访问建议中的调用目标。通知的签名需要包含所有引用的切入点的参数,切入点参数需要引用通知中的参数。
所以,要在建议中有一个 Server
参数,我需要在切入点中使用它,并且需要将它绑定到切入点定义中的某些内容。