gpt4 book ai didi

java - 多方面修改参数提供around advice

转载 作者:搜寻专家 更新时间:2023-10-30 21:33:06 27 4
gpt4 key购买 nike

我有两个方面,每个方面都修改方法参数。当两个方面都应用于同一方法时,我希望这些方面的执行被链接起来,并且我希望在第一个方面修改的参数可以通过 joinPoint.getArgs(); 但是,似乎每个方面都只获得原始参数;第二个方面永远看不到修改后的值。我设计了一个例子:

测试类:

public class AspectTest extends TestCase {
@Moo
private void foo(String boo, String foo) {
System.out.println(boo + foo);
}

public void testAspect() {
foo("You should", " never see this");
}
}

foo() 方法有两个方面的建议:

@Aspect
public class MooImpl {

@Pointcut("execution(@Moo * *(..))")
public void methodPointcut() {}

@Around("methodPointcut()")
public Object afterMethodInControllerClass(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("MooImpl is being called");
Object[] args = joinPoint.getArgs();
args[0] = "don't";
return joinPoint.proceed(args);
}
}

和...

@Aspect
public class DoubleMooImpl {

@Pointcut("execution(@Moo * *(..))")
public void methodPointcut() {}

@Around("methodPointcut()")
public Object afterMethodInControllerClass(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("DoubleMooImpl is being called");
Object[] args = joinPoint.getArgs();
args[1] = " run and hide";
return joinPoint.proceed(args);
}
}

我希望输出是:

MooImpl is being called
DoubleMooImpl is being called
don't run and hide

...但是是:

MooImpl is being called
DoubleMooImpl is being called
You should run and hide

我是否使用正确的方法通过 around advice 修改参数?

最佳答案

这听起来不像是方面排序问题,更多的是 java 中方法参数的处理方式 - 对参数的引用是按值传递的,因为您的第一个参数是字符串,通过修改字符串引用指向的内容您实际上并没有以任何方式影响原始字符串,因此就这样通过了。

您可以尝试传入一个 StringBuilder 或其他一些可变类型,然后修改状态,然后状态更改应该得到正确反射(reflect)。

更新:

我测试了一个可变类型,它按预期变化:

@Moo
private void foo(StringBuilder boo, StringBuilder foo) {
System.out.println(boo.toString() + foo.toString());
}

public void testAspect() {
foo(new StringBuilder("You should"), new StringBuilder(" never see this"));
}

使用 MooImpl 方面:

@Aspect
public class MooImpl {

@Pointcut("execution(@Moo * *(..))")
public void methodPointcut() {}

@Around("methodPointcut()")
public Object afterMethodInControllerClass(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("MooImpl is being called");
Object[] args = joinPoint.getArgs();
((StringBuilder)args[0]).append("****");
return joinPoint.proceed(args);
}
}

和 DoubleMooImpl:

@Aspect
public class DoubleMooImpl {

@Pointcut("execution(@Moo * *(..))")
public void methodPointcut() {}

@Around("methodPointcut()")
public Object afterMethodInControllerClass(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("DoubleMooImpl is being called");
Object[] args = joinPoint.getArgs();
((StringBuilder)args[1]).append("****");
return joinPoint.proceed(args);
}
}

并得到这个输出:

MooImpl is being called
DoubleMooImpl is being called
You should**** never see this****

关于java - 多方面修改参数提供around advice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12843998/

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