Spring 和 AOP - 处理每个抛出的异常

Spring and AOP - handling every thrown exception

我需要拦截每个抛出的异常并对其进行处理。我正在使用这部分代码:

@Aspect
@Component
class Advice
{
    @AfterThrowing(pointcut = "execution(* mail.service..*.*(..))", throwing = "throwable")
    public void sendError(Throwable throwable)
    {
    System.out.println("exception thrown");
    }
}

这与我预期的不一样。这个切入点似乎 'affect' 只有 public 方法(我想这是 Spring AOP 所期望的?)但它只在某些方法中打印字符串,例如,声明的方法在我的 Spring 配置 class 中(我猜是因为它们在应用程序启动之前被初始化)而不是在其他配置中。

我试图让这个方面为任何抛出的异常工作,但我没有成功。这是否与我使用 Spring AOP 而不是完整的 AspectJ 这一事实有某种联系?

另外,我的项目是用Kotlin写的(我把aspect写在Java所以IJ可以支持),这对使用AspectJ有影响吗?我在让它工作时遇到了很多麻烦(因为 final classes),我想知道当我开始编写更高级的 AspectJ 代码时它是否会变得更难。

谢谢!

是的,Spring AOP 仅适用于 Spring 组件并且仅适用于 public 方法(加上 CGLIB 代理的受保护和包保护方法)。它也不适用于像 this.doSomething() 这样的自调用方法,因为它们不通过代理。只有当您的异常升级到通过代理调用的方法之外时,Spring AOP 才能拦截它。

具有 LTW(加载时编织)或 CTW(编译时编织)的 AspectJ 没有任何这些限制,而且您还可以在构造函数中处理异常,而不仅仅是在方法中。

之前从未使用过 Kotlin,我无法告诉您可能存在的问题,但最终 类 本身应该不是问题,因为 AspectJ 直接检测 类' 字节码,而不是通过代理。试试吧。

顺便说一句,以防万一你因为 AOP 而只使用 Spring:你根本不需要使用 Spring 来将 AOP 应用到你的 类 因为 AspectJ 是100% 独立于 Spring。您可以选择一起使用或不使用它们。例如,我从不使用 Spring,而只使用 Java SE + AspectJ。