簡體   English   中英

Aspectj(帶 spring)- 在沒有傳播方法的情況下,僅在拋出方法上記錄異常拋出一次

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

我們剛剛為我們所有的服務方法實現了一個日志方面。 我們還實現了異常拋出日志記錄。

問題是如果我們有以下情況:

ClassA.method1 調用ClassB.method2 調用ClassC.method3,method3 拋出異常。

現在發生的事情是——我們得到了在 method3 AND method2 AND method1 中拋出異常的記錄。 (傳播並因此從每個中重新拋出)

我們如何實現我的方面將只處理最后一個拋出異常的方法(方法 3)?

謝謝!

AspectJ in Action中描述了類似的解決方案。 可以實現很多事情,例如記錄方法名稱,參數等,但是為了簡單起見:

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);
        }
    }
}

一種解決方案可能是將可拋出對象 object 的引用存儲在處理程序 class 中,在其中記錄攔截方法。 保存這些引用的一個好的數據結構可以是WeakSet ,如下所示:

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

在發生異常的情況下,首先,處理程序檢查集合中是否存在異常。 如果不是,則將可拋出的 object 添加到集合中並記錄下來。 如果它存在,則簡單地忽略該異常,因為它是一個傳播的異常,我們確信我們之前記錄過它。

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

使用WeakSet的好處是,每當 throwable object 被 gc 垃圾處理時,它的相關條目會自動從集合中刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM