![](/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.