AspectJ - 围绕控制器请求方法的建议不起作用

时间:2014-08-21 03:15:59

标签: java spring spring-mvc aspectj

尝试在控制器包中调用所有请求方法(所有GET和POST)的around建议。该建议不适用于请求方法。下面是我的控制器和方面建议方法。

另外,我需要打印请求映射参数,例如方法类型(Get或Post)和请求的URL。

控制器类:

package net.prc.sales.web.controller;

// imports

@SessionAttributes({Dictionary.FORM_DRIVER_INFO})
@Controller
public class CustomerInfoController {
    @RequestMapping(value = Dictionary.URL_QUOTE_CUSTOMER_INFO, method = RequestMethod.GET)
    public ModelAndView viewEsCustInfo(Model model, HttpSession session) throws SessionExpiredException {
        ModelAndView mav = new ModelAndView();
        // ...
    }
    // ...
}

Aspect建议:

@Around("net.prc.sales.web.controller.*.*(..) && " + "@annotation(RequestMapping)")
public void ourAroundAdvice(ProceedingJoinPoint method) {
    System.out.println("Before-Advice Part:This is called before the method exceution.\n");
    try {
        method.proceed();
        System.out.println("After-Returning-Advice Part: This is called after the method returns nomally.\n");
    } catch (Throwable e) {
        System.out.println("After-Throwing-Advice Part: This is called after the method throws exception.\n");
    }
}

1 个答案:

答案 0 :(得分:3)

@AleksiYrttiaho是正确的,如果你想匹配子包,你应该使用net.prc.sales.web.controller..*而不是net.prc.sales.web.controller.*.*。但这不是你的问题,因为示例代码显示类CustomerInfoController正好在该包中。

此外,你需要

  • 在切入点的方法签名中指定返回类型
  • 为注释和
  • 指定完全限定的类名
  • 确保您的建议的返回类型与截获的方法类型相匹配。如果截获的方法返回其他内容,则您的建议不能返回void(在您的示例ModelAndView中)。

我还建议重新抛出被抓住的Throwable而不是吞下它。

尝试这样的事情:

@Around("execution(* net.prc.sales.web.controller..*(..)) && @annotation(net.prc.foo.bar.RequestMapping)")
public Object ourAroundAdvice(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    System.out.println("Before " + thisJoinPoint);
    Object result = null;
    try {
        result = thisJoinPoint.proceed();
        System.out.println("After returning " + thisJoinPoint);
        return result;
    } catch (Throwable t) {
        System.out.println("After throwing " + thisJoinPoint);
        throw t;
    }
}

我的建议是在做复杂事情之前先学习AspectJ基础知识。您可以使用本机语法而不是注释样式,因为Eclipse通过语法突出显示和错误消息为您提供了很好的反馈。然后,如果你准备好了切入点,你仍然可以在以后将它转换为@AspectJ语法。


更新:至于将注释绑定到advice参数以便能够访问其属性,这也可以完成,我只是阅读了您的问题的一部分。首先得到建议执行,然后继续(代码未经测试):

@Around("execution(* net.prc.sales.web.controller..*(..)) && @annotation(requestMapping)")
public Object ourAroundAdvice(ProceedingJoinPoint thisJoinPoint, RequestMapping requestMapping) throws Throwable {
    System.out.println("Before " + thisJoinPoint);
    System.out.println("  Request method = " + requestMapping.method());
    System.out.println("  Request value  = " + requestMapping.value());

    Object result = null;
    try {
        result = thisJoinPoint.proceed();
        System.out.println("After returning " + thisJoinPoint);
        return result;
    } catch (Throwable t) {
        System.out.println("After throwing " + thisJoinPoint);
        throw t;
    }
}