Java AOP异常处理

Java AOP异常处理,java,exception-handling,aop,Java,Exception Handling,Aop,我看到Guice和Spring使用AOP Alliance暗中拦截方法,我一直在试图找出如何让AOP Alliance拦截和处理某些异常,这样我就不必在每个catch块中反复编写相同的代码 但是在回顾了剧本之后,AOP联盟似乎没有提供任何拦截抛出的Throwables的方法,这样处理程序/拦截器就可以做一些事情(记录异常等)然后确定是否进一步传播异常,或者只是恢复到引发异常的行后面的下一行: HerpDerp hd = null; if(hd == null) throw new Ru

我看到Guice和Spring使用AOP Alliance暗中拦截方法,我一直在试图找出如何让AOP Alliance拦截和处理某些异常,这样我就不必在每个
catch
块中反复编写相同的代码

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

HerpDerp hd = null;

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

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

  • 如果用Java无法做到这一点,请告诉我
  • 不管在Java中是否可以这样做,是否有一种方法可以通过AOP联盟拦截抛出的异常,或者我必须去其他地方。如果我要去别的地方,在哪里?AspectJ
谢谢

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

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
}

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

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

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

这是不存在的原因。这需要重写代码的块结构,就像您首先编写了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捕获抛出的异常以执行各种任务来处理它,然后返回到异常最初抛出的代码,我认为您不理解AOP的概念

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

HerpDerp hd = null;

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

Manny.pacquiao();
如果您希望AOP捕获您的
运行时异常
,请执行一些操作来处理它,然后返回
Manny.pacquiao(),答案是您不能。
原因是当AOP抛出并捕获
RuntimeException
时,堆栈已经在您的AOP代码中。你不能回来执行
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

之前,谢谢@Wim-这样基于AOP的异常处理在AOP联盟中是不可能的吗?我不这么认为。如果选中,它将显示以下内容:
连接点:程序执行期间的一个点,例如方法执行或异常处理期间的一个点。在SpringAOP中,连接点总是表示方法执行。
可能会被黑客攻击以拦截异常(在构造异常时)?