我正在学习Spring AOP。我只是编写一些非常简单的代码来试一试。在调用ControllerImpl后,我无法理解为什么" re" 为空。我的测试代码中的登录方法。
我只知道有关Spring AOP如何工作的一些知识,也许这就是我无法理解失败的原因。
也许你可以在AopTest.java中运行测试。我使用最新的STS作为我的IDE。
我使用STS调试我的代码,但Spring AOP使用动态代理,所以我看不到详细信息。
你会看到类似的东西" result = null":
This is my test code.At Github.
public class AopTest {
@Autowired
private Controller_ con;
@Test
public void testControllerWithCorrectUid(){
System.out.println("==============================================");
String re = con.login(123);
System.out.println("result = " + re);
System.out.println("==============================================");
assertEquals("success",re);
}
@Test
public void testControllerWithWrongUid(){
System.out.println("==============================================");
String re = con.login(456);
System.out.println("result = " + re);
System.out.println("==============================================");
assertEquals("fail",re);
}
}
答案 0 :(得分:1)
我将分两部分回答:
我使用STS来调试我的代码,但Spring AOP使用动态代理,所以我看不到详细信息。:错误。首先,您可以从Spring框架加载源代码并单步执行其内部类,直到它到达您的内部类,但您可以在您的建议和建议方法中添加断点。
然后,当没有返回值时,控制器返回null的实际原因。看到输出后,我假设login
方法确实返回了一个非空字符串值,可能是success
。但你的周围建议未能将其传回给来电者。
Spring参考手册指出(强调我的):
invoke()方法应该返回调用的结果:连接点的返回值。
甚至举了一个例子:
public class DebugInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Before: invocation=[" + invocation + "]");
Object rval = invocation.proceed();
System.out.println("Invocation returned");
return rval;
}
}
但你的建议是一个void
方法,并且这样的调用者什么也得不到,并且看到了null。建议应该是:
@Around("action()")
public Object logWarn(ProceedingJoinPoint jp) {
Object ret;
System.out.println("AroundAdvice -> LogAspectImpl ");
try {
ret = jp.proceed(); // store the return value of the advised method
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("AroundAdvice -> LogAspectImpl ");
return ret; // and pass it back to caller
}