![](/img/trans.png)
[英]Apply aspect only on annotated methods using AspectJ(without 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.