gpt4 book ai didi

java - 在一个方面结合在同一联接点上运行的前,前后和后建议时,建议优先顺序不清楚

转载 作者:太空宇宙 更新时间:2023-11-04 12:09:31 24 4
gpt4 key购买 nike

请考虑这个简单的Java代码

public class Application {

public void m(int i) {
System.out.println("M with argument " + i );
}

public static void main(String[] arg) {
Application t = new Application();
t.m(25);
}
}


我已经定义了以下方面可用于此类:

public aspect Basics {
public void output(String tag, Object o) {
System.out.println(tag + ": " + o);
}

pointcut callM(int i): call(void Application.m(int)) && args(i);

before(int i): callM(i) {
output("before M", i);
}

void around(int i): callM(i) {
output("around-advice", i);
proceed(1);
output("after proceed", i);
}

after(int i): callM(i) {
output("After M", i);
}
}


值得注意的是,围绕建议会将传递给方法M的参数的值更改为1。
运行此代码将生成以下输出:

before M: 25
around-advice: 25
M with argument 1
after proceed: 25
After M: 25


除了最后一行,整个输出与我预期的一样。我希望最后一行打印“ 1”而不是“ 25”。有人可以向我解释为什么会这样吗?

当我自己寻找答案时,我试图更改建议的顺序,但这最终只会使混乱更大。如果我先将后置建议放在代码中,然后再将前置建议放在代码中,然后将周围建议放在最后(即(1)之后-(2)在之前-(3)附近),则会得到以下输出:

before M: 25
around-advice: 25
M with argument 1
After M: 1
after proceed: 25


对我来说,这是唯一可以完美理解的输出。

但是,如果我把后置建议放在首位,然后将周围建议放在旁,而将前建议放在最后(即(1)之后-(2)前后-(3)之前),则得到以下输出,这也使得如果我考虑先前订单的输出,对我来说毫无意义:

around-advice: 25
before M: 1
M with argument 1
After M: 1
after proceed: 25


在这种情况下,事前通知会以“ i”绑定到1触发。我的猜测是这是由于先行通知是先触发(由于排序),而事前通知实际上是由先行通知触发的。围绕建议的正文中的“继续”调用。但是,遵循此逻辑并不能解释在此问题首先讨论的顺序中生成的输出。

最后,以这样的方式更改顺序:我们首先获得前建议,然后获得后建议,然后再获得前后建议(即(1)之前-(2)之后-(3)左右)根据Eclipse的AspectJ插件无效,因为这会生成“循环建议优先级”。

有人可以给我解释同一方面内不同建议之间使用的优先级的解释,从而解释上述所有行为吗?

我一直在阅读主题 here,但我认为解释是不确定的/与实现不匹配。
它说


  一条周围的建议可控制是否通过调用procedure运行较低优先级的建议。继续进行的调用将以下一个优先级运行建议,如果没有其他建议,则在连接点下进行计算。


如果我理解正确,这意味着在此问题中首先讨论的输出(即(1)之前-(2)周围-(3)排序后)在最后一行应为'1'而不是'25 '。

最佳答案

在同一方面中声明的建议的默认优先级在文档中声明如下:


  如果在同一方面定义了两条建议,则有两种情况:
  
  
  如果有任何建议,则该方面后面出现的建议优先于前面出现的建议。
  否则,则该方面较早出现的那个优先于该较晚出现的一个。
  


但是,您需要了解的是,由于建议是用字节码编织的,因此,您在第一次排序时会得到的结果应如下所示:

 ---------------
| Around() |
| ---------- |
| | Before() | |
| ---------- |
| | Call() | |
| ---------- |
---------------
| After() |
---------------


i的值仅在“环绕”范围内更改,这就是为什么After打印 25值的原因。

在您的第二种情况下,排序给出了类似以下内容:

 ---------------
| Before() |
---------------
| Around() |
| ---------- |
| | Call() | |
| ---------- |
| | After() | |
| ---------- |
---------------


在这种情况下,将按您期望的方式打印值。

关于java - 在一个方面结合在同一联接点上运行的前,前后和后建议时,建议优先顺序不清楚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39978586/

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