简体   繁体   English

Aspectj(带 spring)- 在没有传播方法的情况下,仅在抛出方法上记录异常抛出一次

[英]Aspectj (with spring) - logging throw of an exception only once on the throwing method without the propagated methods

We just implemented a logging aspect for all of our services methods.我们刚刚为我们所有的服务方法实现了一个日志方面。 We Implemented exception throwing logging as well.我们还实现了异常抛出日志记录。

Problem is if we have the following scenario:问题是如果我们有以下情况:

ClassA.method1 calls ClassB.method2 calls ClassC.method3 and method3 throws an exception. ClassA.method1 调用ClassB.method2 调用ClassC.method3,method3 抛出异常。

What happens now is - we got a logging of the exception throwing in method3 AND method2 AND method1.现在发生的事情是——我们得到了在 method3 AND method2 AND method1 中抛出异常的记录。 (the excpetion is propagated and therefore rethrown from each) (传播并因此从每个中重新抛出)

How can we achieve that my aspect will handle only the last method throwing the exception (method3)?我们如何实现我的方面将只处理最后一个抛出异常的方法(方法 3)?

Thanks!谢谢!

Similar solution was described in AspectJ in Action. AspectJ in Action中描述了类似的解决方案。 There's lots of things that might be implemented like logging of method name, arguments etc, but for simplicity sake : 可以实现很多事情,例如记录方法名称,参数等,但是为了简单起见:

public aspect ExceptionAspect {
    private Log log = Logger.getLogger("error_log");
    private Exception exception;

    pointcut exceptionPointcut() : execution(* my.package..*(..));

    after() throwing(Exception ex) : exceptionPointcut() {
        if (exception != ex) {
            exception = ex;
            log.error("ERROR: {}", ex);
        }
    }
}

A solution could be to store a reference of the throwable object in the handler class in which intercept methods to log.一种解决方案可能是将可抛出对象 object 的引用存储在处理程序 class 中,在其中记录拦截方法。 A good data structure for holding these references can be WeakSet , something like below:保存这些引用的一个好的数据结构可以是WeakSet ,如下所示:

Set<Throwable> throwableRecord = Collections.newSetFromMap(new WeakHashMap<>());

In the case of an occurring exception, at first, the handler checks whether the exception exists in the set or not.在发生异常的情况下,首先,处理程序检查集合中是否存在异常。 If not, the throwable object is added to the set and is also logged.如果不是,则将可抛出的 object 添加到集合中并记录下来。 If it exists, simply ignore the exception since it is a propagated exception, and we are sure that we logged it before.如果它存在,则简单地忽略该异常,因为它是一个传播的异常,我们确信我们之前记录过它。

if (throwableRecord.contains(throwable)) {
    //dont't log
    //the exception is logged before
}
throwableRecord.add(throwable);
//log the exception

The benefit of using WeakSet is that, whenever the throwable object is garbaged by gc, its related entry is automatically removed from the set.使用WeakSet的好处是,每当 throwable object 被 gc 垃圾处理时,它的相关条目会自动从集合中删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM