AOPexception处理

我看到Guice和Spring使用AOP联盟进行方法拦截,我一直试图弄清楚如何让AOP联盟拦截和处理某些exception,所以我不必继续编写相同的代码。在每个catch区内再次出现。

但是在审查了游戏之后,看起来AOP联盟并没有提供任何方法来拦截抛出的Throwable s,使得处理程序/拦截器可以执行某些操作(记录exception等),然后确定是否进一步传播exception,或者只是恢复到引发exception的行之后的下一行

 HerpDerp hd = null; if(hd == null) throw new RuntimeException("Herpyl derp!"); Manny.pacquiao(); 

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

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

谢谢!

您可以使用Spring AOP捕获exception,但我不知道这是否符合您对纯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."); } } } 

但是无法返回调用方法或继续处理后续行。 但是,如果你在这里处理exception,除非你自己重新抛出它,否则它不会起泡链。

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

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

@ 4herpsand7derpsago如果您要做的是使用AOP捕获抛出的exception来执行各种任务来处理它,然后回到最初抛出exception的代码,我想您错过了AOP的概念。

正如你在代码中指出的那样

 HerpDerp hd = null; if(hd == null) throw new RuntimeException("Herpyl derp!"); Manny.pacquiao(); 

如果你希望AOP捕获你的RuntimeException ,执行一些东西来处理它并回到Manny.pacquiao(); ,答案是你不能 。 原因是当抛出RuntimeException并被AOP捕获时,堆栈已经在您的AOP代码中。 你不能回来执行Many.pacquiao(); 。 如果你想继续执行Many.pacquiao();的唯一方法Many.pacquiao(); 是通过使用try-finally块如下

 HerpDerp hd = null; try { if(hd == null) throw new RuntimeException("Herpyl derp!"); } finally { Manny.pacquiao(); } 

只有这样你的Many.pacquiao()才会被执行,但是在你的AOP捕获RuntimeException

要使用AspectJ“捕获”未捕获的exception,您可以使用以下方面:

 pointcut uncaughtExceptionScope() : (execution(* com.mycompany.myrootpackage..Main.main(..)) || execution(* java.util.concurrent.Callable+.call()) || execution(* java.lang.Runnable+.run()) )); after() throwing(Throwable t) : uncaughtExceptionScope() && !cflow(adviceexecution()) { handleException(thisJoinPoint, t); } protected void handleException(JoinPoint jp, Throwable t) { // handle exception here } 

我不认为有可能“回到”执行点。