AOP 异常处理

2022-09-01 16:58:29

我看到Guice和Spring在引擎盖下使用AOP联盟进行方法拦截,我一直在努力弄清楚如何让AOP联盟拦截和处理某些异常,这样我就不必在每个块中一遍又一遍地编写相同的代码。catch

但是在回顾了重头戏之后,AOP联盟似乎没有提供任何方法来拦截抛出的s,以便处理程序/拦截器可以做一些事情(记录异常等),然后确定是否进一步传播异常或只是恢复到抛出异常的行后面的下一行Throwable

HerpDerp hd = null;

if(hd == null)
    throw new RuntimeException("Herpyl derp!");

Manny.pacquiao();

我正在寻找一种AOP异常处理机制,该机制将拦截并使用业务逻辑来决定是继续传播它还是在调用时恢复。RuntimeExceptionManny.pacquioa()

  • 如果无法在Java中执行此操作,请告诉我
  • 无论在Java中是否有可能做到这一点,是否有一种方法可以拦截AOP联盟的抛出异常,或者我必须去别的地方。如果我必须去别的地方,在哪里?AspectJ?

谢谢!


答案 1

您可以使用Spring AOP捕获异常,但我不知道这是否符合您对纯Java框架的要求。

使用Spring,您可以将一个简单的AOP拦截器编写如下内容:

@Aspect
public class ErrorInterceptor{
@AfterThrowing(pointcut = "execution(* com.mycompany.package..* (..))", throwing = "ex")
public void errorInterceptor(WidgetException ex) {
    if (logger.isDebugEnabled()) {
        logger.debug("Error Message Interceptor started");
    }

    // DO SOMETHING HERE WITH EX
    logger.debug( ex.getCause().getMessage());


    if (logger.isDebugEnabled()) {
        logger.debug("Error Message Interceptor finished.");
    }
}
}

但无法返回到调用方法或在后续行上继续处理。但是,如果您在此处处理异常,除非您自己将其重新抛出,否则它不会在链上冒泡。


答案 2

这不存在是有原因的。这需要重写代码的块结构,就好像你首先编写了try/catch块一样。在我看来,这可能会对可变范围和其他事情造成严重破坏。您要求AOP将字节代码重写为类似于以下代码的内容,这是一次重写。

HerpDerp hd = null;

try {
    if(hd == null)
        throw new RuntimeException("Herpyl derp!");
} catch(RuntimeException e) {
   if (someConditionIsMet) {
       throw e;
   }
}

Manny.pacquiao();

推荐