Spring AOP@AfterThroung-获取并记录调用的方法详细信息(不调用方法)



主要问题-如果一个方法遇到错误,我想使用Spring AOP来记录该方法的参数,即如果该方法的执行中出现异常,并且该异常被抛出到调用方法。

我能做上面的事情吗?看起来@AfterThrowing记录了调用方法的详细信息,但没有记录被调用的方法(错误实际发生的地方)。

这就是我的

技术堆栈-

  1. 弹簧套1.3.5

我的@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>

可以看出,它记录的是"调用方法"和相关项目与"被调用方法"——错误实际发生的地方。

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

考虑的备选方案-

  1. 现在,我可以使用AOP记录每个方法条目和params,但我不想混淆日志/性能,因为我知道只有在出现异常时才需要params
  2. 当然,我可以用try/catch块在每个方法中记录这一点,但这意味着必须大量重复样板代码

我已经搜索了许多论坛,其中有关于如何让AOP工作等的详细信息,但找不到上面询问/讨论的内容。这是(我能找到的)唯一一篇关于调用与调用的帖子,但不是这个问题的答案——SpringAOP with groovy:getcalledmethod

请让我知道我们是否能做到我想要的/这是否是正确的(或有效的)方式。非常感谢。

如果一切都实现正确,我希望日志输出会出现多次——对于Spring组件中的每个公共非静态方法都会出现一次(!),从而将错误抛出调用堆栈。这真的是你想要的吗?同一个异常记录了多次?不管怎么说,你似乎就是这么想的。

对观察到的行为产生了一些解释:

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

最新更新