Spring AOP @AfterThrowing - get和log调用方法细节(不调用方法)

时间:2016-07-20 22:21:17

标签: java spring aop

主要问题 - 如果该方法遇到错误,我想使用Spring AOP来记录方法的参数 - 即如果在该方法的执行中存在异常并且该异常是扔到调用方法。

我能做到吗?似乎@AfterThrowing记录调用方法的详细信息,但不记录被调用的方法(实际发生错误的地方)。

这就是我所拥有的 -

技术堆栈 -

  1. Spring Boot 1.3.5
  2. 我的@Aspect类 -

    @Aspect
    @Component
    public class LoggingAspect {
    @AfterThrowing(pointcut = "execution(* com.spicedcider.service..*.*(..))", throwing = "e")
    public void logExceptionContext(JoinPoint joinPoint, Throwable e) {
        Object[] params = joinPoint.getArgs();
    
        log.error("Exception while executing method below - ");
        log.error("[" + joinPoint.getStaticPart().getSignature() + "]");
        log.error("Exception message - " + e.getMessage());
        log.error("Full stack trace logged further below");
    
        log.error("Params for this method - ");
        for (Object object : params) {
            log.error(object == null ? "[is null]" : object.toString());
        }
    }
    

    以上情况很有效 - 如果流程如下,

    主要通话方式

    public void executeBusinessLogic(String var1, String var2) {
        /* some activities */
        String myName = "Spiced Cider";
        returnObject = anotherService.executeSubLogic(myName);
    
        /* more activities based on returnObject */
    }
    

    支持方法

    public Object executeSubLogic(String name) {
        /* an exception occurs here and is thrown to executeBusinessLogic() */
    }
    

    现在,AOP记录如下。

    [ERROR] [..LoggingAspect.logExceptionContext] - Exception while executing method below - 
    [ERROR] [..LoggingAspect.logExceptionContext] - [void executeBusinessLogic()]
    [ERROR] [..LoggingAspect.logExceptionContext] - Exception message - <message>
    [ERROR] [..LoggingAspect.logExceptionContext] - Full stack trace logged further below
    [ERROR] [..LoggingAspect.logExceptionContext] - Params for this method - 
    [ERROR] [..LoggingAspect.logExceptionContext] - <var1 value>
    [ERROR] [..LoggingAspect.logExceptionContext] - <var2 value>
    

    可以看出,它正在记录“调用方法”和相关项目与“被调用方法” - 实际发生错误的地方。

    我需要这个的原因 - 这是从调试的角度来看。发生异常时,我需要知道传递给异常发生的方法的参数。

    考虑替代 -

    1. 现在我可以使用AOP记录每个方法条目和参数 - 但我不想让日志/性能混乱 - 只有在出现异常时才知道params。
    2. 我当然可以使用try / catch块在每个方法中记录它,但这意味着必须重复使用样板代码。
    3. 我搜索了许多论坛,其中有关于如何让AOP工作等的详细信息,但找不到上述问题/讨论过。这是唯一一个谈论被叫与召唤的其他帖子(我可以找到) - 但这不是这个问题的答案 - Spring AOP with groovy: get called method

      如果我们能够做我正在寻找的事情/如果这是正确的(或有效的)方式,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:0)

如果一切正确实现,我希望日志输出多次出现 - 一次为Spring组件中的每个公共非静态方法(!)抛出callstack错误。这真的是你想要的吗?多次记录相同的异常?无论如何,似乎你想要的确如此。

对于观察到的行为,我们会想到一些解释:

  • 类声明方法executeSubLogic(..) 是一个Spring bean /组件。因为你似乎使用Spring AOP,而不是成熟的AspectJ,所以AOP框架只能拦截Spring组件的公共方法。
  • 类声明方法executeSubLogic(..)是一个Spring bean /组件,但它没有实现接口。为了为类(而不是接口)创建动态代理,Spring需要CGLIB,但由于某种原因,lib不在你的类路径上。
  • 您的切入点会捕获包com.spicedcider.service中包含的所有方法执行。子包,但类声明方法executeSubLogic(..)在该包中