我的 SpringAOP 演示代码中出现了一些错误,其中包含 null

Something is wrong in my SpringAOP Demo code with a null

我正在学习SpringAOP.I只是写了一些很简单的代码有一个try.I无法理解为什么"re"在我的测试代码中调用ControllerImpl的登录方法后为null。

我对SpringAOP的工作原理只知道一些知识,可能是我无法理解失败的原因。

也许你可以 运行 AopTest.java.I 中的测试我使用最新的 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);
}

}

我分两部分回答:

我用STS调试我的代码,但是SpringAOP使用动态代理,所以我看不到细节。:错误。首先,您可以从 Spring 框架加载源代码并单步执行其内部 类 直到它到达您的框架,但您可以只在建议和建议方法中放置断点。

那么当 return 的 return 值的 none 是时,您的控制器 returning null 的实际原因是。看到你的输出后,我假设 login 方法做了 return 一个非空字符串值,可能是 success。但是您的 around advice 未能将其传回给调用者。

Spring 参考手册指出(强调我的):

The invoke() method should return the invocation’s result: the return value of the join point.

甚至举个例子:

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

但是您的 around advice 是一个 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
}