Следующее не обрабатывает случай автоматической регистрации всех исключений, но может приблизить вас. В моей нынешней компании мы расширили Exception
с CompanyException
, который поддерживал список обратных вызовов. Что-то вроде:
public abstract class CompanyException extends Exception {
private static final List<ExceptionCallback> callBacks =
new ArrayList<ExceptionCallback>();
public CompanyException(String message) {
super(message);
invokeCallbacks();
}
// register class to be called whenever exception is constructed
public static void registerCallback(ExceptionCallback callback) {
// we expect the registers to be done long before the first exception thrown
List<ExceptionCallback> newCallbacks = new ArrayList<ExceptionCallback>();
newCallBacks.addAll(callBacks);
newCallbacks.add(callback);
callBacks = newCallBacks;
}
private void invokeCallbacks() {
for (ExceptionCallback callBack : callBacks) {
try {
callBack.exceptionConstructed(this);
} catch (Throwable th) {
// ignore it because we can't go recursive
}
}
}
}
Обратный вызов был простым интерфейсом:
public interface ExceptionCallback {
public void exceptionConstructed(Exception exception);
}
Тогда все наши внутренние исключения будут выбрасывать эти или отбрасывать / переносить внешние исключения. Затем мы зарегистрируем класс ведения журнала, который может регистрировать исключения, используя log4j или наши внутренние механизмы ведения журнала. Очевидно, что исключение может выполнять саму регистрацию, но мы хотели разделения. У нашего регистратора был специальный поток, чтобы сделать это в фоновом режиме и отправить его на центральный сервер регистрации. Вы должны быть очень осторожными в отношении рекурсии, если вы бросаете во время регистрации.