gpt4 book ai didi

java - 阅读和理解 AspectJ 切入点?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:10:42 29 4
gpt4 key购买 nike

/* 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 的切入点,但现在有点困惑。我的主要问题是:您如何解读上述切入点,以及如何将其含义“拼凑”在一起?

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

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

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

现在,这个怎么样:

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

我假设在调用 Server 对象的公共(public)方法时会拦截任何点。

现在,我如何从这里到达初始示例 0?我该如何阅读?

在构建切入点时,您会先提供参数列表吗?

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

这与上面的数字 2 相同吗? (我觉得它不会起作用,如果它起作用,它会“拦截”每个公共(public)方法调用,就像数字 1 一样。)不管怎样,下面是一样的吗? (我还没有用原生切入点“捕获”s,所以我不能真正定义它,对吗?)

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

或者您会先指定一个本地切入点,以“捕获”目标对象,如下所示:

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

我想这仍然会拦截对任何对象的所有公共(public)方法调用吗?

下面的工作是否只拦截对服务器对象的调用,并“捕获”该对象(而不使其可用于以后传递,例如通知)?

/* 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 切入点的参数类型并“从里到外”/“从右到左”阅读它?还是先查看参数列表,然后查看 services 切入点以查看参数来自何处(即 target(s))?

还是我把它弄得太复杂了?我是否遗漏了重要的一点来帮助我理解这一点?

编辑: 手册从左到右对其进行了解释 - 但是如果我没有“执行”target,参数 Server s 的参数从哪里来(s) 了吗?

最佳答案

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

2:它拦截对声明作为服务器的对象的任何公共(public)方法调用,而0拦截对作为实例的对象的任何公共(public)调用>服务器。参见 the semantics .

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

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

4a: 语法无效,就像在接口(interface)中声明方法时需要命名参数一样:

[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不同,它只匹配公共(public)Server方法调用(即在Server中声明)到一个服务器实例。

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

您可以(并且应该)自己尝试,以获得更好的理解。


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

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

关于java - 阅读和理解 AspectJ 切入点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28969333/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com