我的SpringAOP演示代码中有一些错误

时间:2016-03-22 07:20:34

标签: java spring aop spring-aop

我正在学习Spring AOP。我只是编写一些非常简单的代码来试一试。在调用ControllerImpl后,我无法理解为什么" re" 为空。我的测试代码中的登录方法。

我只知道有关Spring AOP如何工作的一些知识,也许这就是我无法理解失败的原因。

也许你可以在AopTest.java中运行测试。我使用最新的STS作为我的IDE。

我使用STS调试我的代码,但Spring AOP使用动态代理,所以我看不到详细信息。

你会看到类似的东西" result = null":

Click to see my test output.

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);
}

}

1 个答案:

答案 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
}