Aspectj "после броска" - отслеживать конкретное исключение
Я пытаюсь поймать все исключения MySpecificException, выброшенные из кода приложения через aspectj.
Есть много мест, где это исключение может быть выброшено. Как только исключение выдается, я хочу зарегистрировать его или выполнить какую-либо операцию (независимо от того, было ли оно перехвачено позднее или нет).
Я пытался использовать:
@AfterThrowing(value = "(execution(* *.*(..))), throwing = "throwable")
но это перебор, так как он ловит все исключения. Я могу фильтровать вручную позже, но я пытаюсь избежать этого (из-за природы моих приложений, в некоторых случаях это вызывает проблемы со временем загрузки из-за проблем с загрузчиком классов)
Я также попробовал:
@AfterThrowing(value = "(execution(* *.*(..))) throws MySpecificException, throwing = "throwable")
но этого недостаточно, поскольку что, если метод объявляет, что он вызывает много исключений?
Любые предложения о том, как отлавливать только мои соответствующие исключения, не фильтруя их внутри реализации pointcut?
Спасибо
1 ответ
Ваш код не является исполняемым, пожалуйста, предоставьте MCVE или хотя бы полный аспект в следующий раз. Вы даже не предоставляете подпись совета. Это не хороший способ задавать вопросы о SO. Как пользователь с 1000+ очками репутации, вы должны это знать.
Во всяком случае, ответ на ваш вопрос на самом деле очень прост. Предполагая, что у вас есть этот пример кода:
Класс исключения + приложение драйвера:
package de.scrum_master.app;
public class MySpecificException extends Exception {
private static final long serialVersionUID = 1L;
}
package de.scrum_master.app;
import java.io.IOException;
public class Application {
public String doSomething(Integer number) {
return number.toString();
}
public void doSomethingElse(boolean doThrow) throws MySpecificException {
if (doThrow)
throw new MySpecificException();
}
public void doWhatever(boolean doThrow) throws MySpecificException, IOException {
if (doThrow)
throw new MySpecificException();
else
throw new IOException();
}
public static void main(String[] args) throws MySpecificException, IOException {
Application application = new Application();
// Just so as not to mess up the console output in the IDE for this demo
System.setErr(System.out);
// No exceptions here
application.doSomething(11);
application.doSomethingElse(false);
// Let's catch some exceptions
try {
application.doSomethingElse(true);
} catch (MySpecificException e) {
System.out.println("Caught " + e);
}
try {
application.doWhatever(true);
} catch (MySpecificException e) {
System.out.println("Caught " + e);
}
try {
application.doWhatever(false);
} catch (IOException e) {
System.out.println("Caught " + e);
}
// Do not catch this one
application.doSomethingElse(true);
}
}
Консольный журнал без аспекта:
Caught de.scrum_master.app.MySpecificException
Caught de.scrum_master.app.MySpecificException
Caught java.io.IOException
Exception in thread "main" de.scrum_master.app.MySpecificException
at de.scrum_master.app.Application.doSomethingElse(Application.java:12)
at de.scrum_master.app.Application.main(Application.java:50)
Здесь нет сюрпризов. Мы поймали и выловили исключения разных типов. Теперь мы хотим, чтобы аспект регистрировал все случаи MySpecificException
независимо от того, поймали они или нет.
аспект:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import de.scrum_master.app.MySpecificException;
@Aspect
public class ExceptionLogger {
@AfterThrowing(value = "(execution(* *.*(..)))", throwing = "mySpecificException")
public void logException(JoinPoint thisJoinPoint, MySpecificException mySpecificException) {
System.out.println(thisJoinPoint + " -> " + mySpecificException);
}
}
Видите подпись метода совета? Просто ограничьте параметр исключения желаемым типом.
Консольный журнал с аспектом:
execution(void de.scrum_master.app.Application.doSomethingElse(boolean)) -> de.scrum_master.app.MySpecificException
Caught de.scrum_master.app.MySpecificException
execution(void de.scrum_master.app.Application.doWhatever(boolean)) -> de.scrum_master.app.MySpecificException
Caught de.scrum_master.app.MySpecificException
Caught java.io.IOException
execution(void de.scrum_master.app.Application.doSomethingElse(boolean)) -> de.scrum_master.app.MySpecificException
execution(void de.scrum_master.app.Application.main(String[])) -> de.scrum_master.app.MySpecificException
Exception in thread "main" de.scrum_master.app.MySpecificException
at de.scrum_master.app.Application.doSomethingElse(Application.java:12)
at de.scrum_master.app.Application.main(Application.java:50)