【问题标题】:Aspectj "after throwing" - monitor a specific exceptionAspectj "after throwing" - 监控特定异常
【发布时间】:2018-01-17 08:55:41
【问题描述】:

我正在尝试通过 aspectj 捕获从应用程序代码中抛出的所有 MySpecificException 异常。

有很多地方可以抛出这个异常。 一旦抛出异常,我想记录它或做一些操作(不管它是否后来被捕获)。

我尝试过使用:

@AfterThrowing(value = "(execution(* *.*(..))), throwing = "throwable")

但这是一个矫枉过正,因为它捕获了所有的异常。我可以稍后手动过滤,但我试图避免这种情况(由于我的应用程序性质,在某些情况下由于类加载器问题会导致加载时间问题)

我也试过了:

@AfterThrowing(value = "(execution(* *.*(..))) throws MySpecificException, throwing = "throwable")

但这还不够,因为如果方法声明它会抛出很多异常怎么办?

关于如何只捕获我的相关异常而不在切入点实现中过滤它们的任何建议?

谢谢

【问题讨论】:

    标签: java aspectj pointcut


    【解决方案1】:

    您的代码不可执行,请在下次提供MCVE 或至少提供完整方面。您甚至不提供建议的签名。这不是就 SO 提出问题的好方法。作为拥有 1,000 多个声望点的用户,您应该知道这一点。

    不管怎样,你的问题的答案其实很简单。假设你有这个示例代码:

    异常类+驱动应用:

    package de.scrum_master.app;
    
    public class MySpecificException extends Exception {
      private static final long serialVersionUID = 1L;
    }
    
    package de.scrum_master.app;
    
    import java.io.IOException;
    
    public class Application {
      public String doSomething(Integer number) {
        return number.toString();
      }
    
      public void doSomethingElse(boolean doThrow) throws MySpecificException {
        if (doThrow)
          throw new MySpecificException();
      }
    
      public void doWhatever(boolean doThrow) throws MySpecificException, IOException {
        if (doThrow)
          throw new MySpecificException();
        else
          throw new IOException();
      }
    
      public static void main(String[] args) throws MySpecificException, IOException {
        Application application = new Application();
    
        // Just so as not to mess up the console output in the IDE for this demo
        System.setErr(System.out);
    
        // No exceptions here
        application.doSomething(11);
        application.doSomethingElse(false);
    
        // Let's catch some exceptions
        try {
          application.doSomethingElse(true);
        } catch (MySpecificException e) {
          System.out.println("Caught " + e);
        }
        try {
          application.doWhatever(true);
        } catch (MySpecificException e) {
          System.out.println("Caught " + e);
        }
        try {
          application.doWhatever(false);
        } catch (IOException e) {
          System.out.println("Caught " + e);
        }
    
        // Do not catch this one
        application.doSomethingElse(true);
      }
    }
    

    没有方面的控制台日志:

    Caught de.scrum_master.app.MySpecificException
    Caught de.scrum_master.app.MySpecificException
    Caught java.io.IOException
    Exception in thread "main" de.scrum_master.app.MySpecificException
        at de.scrum_master.app.Application.doSomethingElse(Application.java:12)
        at de.scrum_master.app.Application.main(Application.java:50)
    

    这里没有惊喜。我们已经捕获和未捕获的不同类型的异常。现在我们希望有一个方面专门记录所有出现的MySpecificException,无论它们是否被捕获。

    方面:

    package de.scrum_master.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    
    import de.scrum_master.app.MySpecificException;
    
    @Aspect
    public class ExceptionLogger {
      @AfterThrowing(value = "(execution(* *.*(..)))", throwing = "mySpecificException")
      public void logException(JoinPoint thisJoinPoint, MySpecificException mySpecificException) {
        System.out.println(thisJoinPoint + " -> " + mySpecificException);
      }
    }
    

    看到通知方法的签名了吗?只需将异常参数限制为所需的类型即可。

    带有方面的控制台日志:

    execution(void de.scrum_master.app.Application.doSomethingElse(boolean)) -> de.scrum_master.app.MySpecificException
    Caught de.scrum_master.app.MySpecificException
    execution(void de.scrum_master.app.Application.doWhatever(boolean)) -> de.scrum_master.app.MySpecificException
    Caught de.scrum_master.app.MySpecificException
    Caught java.io.IOException
    execution(void de.scrum_master.app.Application.doSomethingElse(boolean)) -> de.scrum_master.app.MySpecificException
    execution(void de.scrum_master.app.Application.main(String[])) -> de.scrum_master.app.MySpecificException
    Exception in thread "main" de.scrum_master.app.MySpecificException
        at de.scrum_master.app.Application.doSomethingElse(Application.java:12)
        at de.scrum_master.app.Application.main(Application.java:50)
    

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 2019-12-07
      • 2019-03-30
      • 1970-01-01
      • 2011-03-19
      • 2011-07-24
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      相关资源
      最近更新 更多