Ответ 1
Вам необходимо использовать инструменты АОП, такие как CDI Interceptor или AspectJ, для решения этой сквозной задачи. Концерн - это термин, который относится к части системы, разделенной по функциональности.
В основном, этот тип функций используется для ведения журналов, обеспечения безопасности, а также обработки ошибок... которые не являются частью вашей бизнес-логики...
Например, если вы хотите изменить регистратор для приложения с log4j на sl4j, вам нужно пройти через все классы, где вы использовали log4j, и изменить его. Но если вы использовали инструменты AOP, вам нужно только перейти к классу перехватчиков и изменить реализацию. Что-то вроде подключи и играй и очень мощный инструмент.
Вот фрагмент кода с использованием JavaEE CDI Interceptor
/*
Creating the interceptor binding
*/
@InterceptorBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface BindException {
}
После того, как мы определим привязку перехватчика, нам нужно определить реализацию привязки перехватчика
/*
Creating the interceptor implementation
*/
@Interceptor
@BindException
public class ExceptionCDIInterceptor {
@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
System.out.println("Invoked method " + ctx.getMethod().getName());
try {
return ctx.proceed(); // this line will try to execute your method
// and if the method throw the exception it will be caught
} catch (Exception ex) {
// here you can check for your expected exception
// code for Exception handler
}
}
}
Теперь нам нужно только применить перехватчик к нашему методу
/*
Some Service class where you want to implement the interceptor
*/
@ApplicationScoped
public class Service {
// adding annotation to thisMethodIsBound method to intercept
@BindException
public String thisMethodIsBound(String uid) {
// codes....
// if this block throw some exception then it will be handled by try catch block
// from ExceptionCDIInterceptor
}
}
Вы можете достичь той же функции, используя AspectJ также.
/*
Creating the Aspect implementation
*/
@Aspect
public class ExceptionAspectInterceptor {
@Around("execution(* com.package.name.SomeService.thisMethodIsBound.*(..))")
public Object methodInterceptor(ProceedingJoinPoint ctx) throws Throwable {
System.out.println("Invoked method " + ctx.getSignature().getName());
try {
return ctx.proceed(); // this line will try to execute your method
// and if the method throw the exception it will be caught
} catch (Exception ex) {
// here you can check for your expected exception
// codes for Exception handler
}
}
}
Теперь нам нужно только включить AspectJ в конфигурацию нашего приложения
/*
Enable the AspectJ in your application
*/
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public SomeService SomeService() {
return new SomeService();
}
}
/*
Some Service class where you want to implement the Aspect
*/
package com.package.name;
public class SomeService {
public String thisMethodIsBound(String uid) {
// codes....
// if this block throw some exception then it will be handled by try catch block
// from ExceptionAspectInterceptor
}
}
У меня есть пример кода в моем репозитории git https://github.com/prameshbhattarai/javaee-exceptionBinding с использованием перехватчика CDI.