【问题标题】:Spring AOP Exception handling Advice not executed if catch block is thereSpring AOP 异常处理 如果存在 catch 块,则不执行建议
【发布时间】:2018-06-19 09:27:39
【问题描述】:

我正在使用 Spring AOP 在我的班级中记录异常。它应该记录类的每个方法中抛出的所有异常。

@AfterThrowing(pointcut = "execution(* *.*(..))", throwing = "e")
protected void method(JoinPoint joinPoint,Exception e) throws Throwable {

但是,如果该方法有一个捕获异常的 try catch 块,则不会触发通知。如果我删除 try catch 块并在方法定义中添加 throws 子句,则会调用建议。这是 AOP 应该如何工作的,因为它没有任何意义?我只想在一个地方而不是在每个方法中为所有异常提供一个通用的异常处理代码。

【问题讨论】:

标签: java spring aspectj spring-aop


【解决方案1】:

是的,这就是它应该的工作方式。术语“抛出后”已经说明了建议何时开始:在目标方法抛出异常之后。不过,您的方法会捕获并且永远不会抛出您想要拦截的异常。那你能做什么呢?

  • 您要么必须在调用链的上一级或多级拦截它,要么
  • 您从 Spring AOP 升级到 AspectJ 并使用handler() 切入点来拦截您的方法中的catch 块,如AspectJ manual 中所述。您还可以在my answer to another question 中找到handler() 的示例代码。 Spring manual 中描述了如何使用 LTW 激活完整的 AspectJ。

作为旁注,我想知道您为什么首先尝试拦截(希望正确)处理的异常。您的示例代码在哪里?你的用例是什么?

【讨论】:

  • 感谢@kriegaex,我认为spring AOP 比完整的AspectJ 更容易实现,并且与我在Web 应用程序上工作时更相关。我的用例是我想避免样板记录代码。我想在一个地方为多个类和方法记录方法进入和退出以及异常。在异常中,我想记录方法名称、异常、参数。
  • 方法入口退出建议对我的 DAO 工作正常,但我不知道如何为我的 servlet 实现它,因为它不是 Spring 应用程序,并且 Spring AOP 仅适用于 Spring 注入的 bean。异常建议没有按预期工作,因为我无法将未捕获的异常从 DAO 抛出到 servlet。我需要建议在 DAO 和 servlet 中记录异常。
  • 好吧,我的解释已经回答了这些问题:使用 AspectJ 而不是 spring AOP。 AspectJ 可以在 Spring 中使用,但在其他方面完全不相关且独立,如果配置正确,它可以与任何 Java(或其他 JVM 语言)应用程序一起使用。所以我很感激你接受我的回答。谢谢。
【解决方案2】:

如果您使用 try catch 处理方法中的异常,则该方法不会抛出该异常。 AOP只关心方法的输入和输出,把它当成一个黑盒子,不关心方法内部发生了什么。

也许您可以将 try catch 移至调用方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2019-11-29
    • 2012-06-12
    • 1970-01-01
    相关资源
    最近更新 更多