我有两个方面,每个方面修改方法参数.当两个方面都应用于同一个方法时,我希望将方面的执行链接起来,并且我希望第一个方面中修改的参数可用于第二个方面.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");
}
}
Run Code Online (Sandbox Code Playgroud)
方法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);
}
}
Run Code Online (Sandbox Code Playgroud)
和...
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望输出为:
MooImpl is being called
DoubleMooImpl is being called
don't run and hide
Run Code Online (Sandbox Code Playgroud)
...但是:
MooImpl is being called
DoubleMooImpl is being called
You should run and hide
Run Code Online (Sandbox Code Playgroud)
我是否使用正确的方法通过建议修改参数?
这听起来不像是方面排序问题,它更多的是如何在 java 中处理方法参数 - 对参数的引用是按值传递的,因为你的第一个参数是一个字符串,通过修改字符串引用指向你不是确实以任何方式影响原始字符串,因此被传递。
您可以尝试传入 StringBuilder 或其他可变类型,然后修改状态,然后状态更改应该得到正确反映。
更新:
我使用可变类型进行了测试,它按预期更改:
@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"));
}
Run Code Online (Sandbox Code Playgroud)
与 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);
}
}
Run Code Online (Sandbox Code Playgroud)
和 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);
}
}
Run Code Online (Sandbox Code Playgroud)
并得到这个输出:
MooImpl is being called
DoubleMooImpl is being called
You should**** never see this****
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5008 次 |
| 最近记录: |