Aspectj (с пружиной) - регистрация выброса исключения только один раз в методе throwing без распространяемых методов

Мы только что реализовали аспект ведения журнала для всех наших методов обслуживания. Мы также реализовали ведение журнала исключений.

Проблема в том, что у нас есть следующий сценарий:

ClassA.method1 вызывает ClassB.method2 вызывает ClassC.method3, а method3 создает исключение.

То, что происходит сейчас, - мы получили запись исключения, генерируемого в method3 AND method2 AND method1. (исключение распространяется и поэтому отбрасывается от каждого)

Как мы можем добиться того, чтобы мой аспект обрабатывал только последний метод, выдавший исключение (method3)?

Спасибо!

2 ответа

Решение может состоять в том, чтобы сохранить ссылку на бросаемый объект в классе обработчика, в котором будут зарегистрированы методы перехвата. Хорошая структура данных для хранения этих ссылок может выглядеть примерно так:

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

В случае возникновения исключения сначала обработчик проверяет, существует ли исключение в наборе или нет. Если нет, бросаемый объект добавляется в набор и также регистрируется. Если оно существует, просто игнорируйте исключение, так как это распространенное исключение, и мы уверены, что зарегистрировали его раньше.

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

Преимущество использованиязаключается в том, что всякий раз, когда бросаемый объект удаляется сборщиком мусора, связанная с ним запись автоматически удаляется из набора.

Подобное решение было описано в AspectJ в действии. Есть много вещей, которые могут быть реализованы, такие как регистрация имени метода, аргументов и т. Д., Но для простоты:

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);
        }
    }
}
Другие вопросы по тегам