[SPRING] Spring Async Uncaught Exception 핸들러
SPRINGSpring Async Uncaught Exception 핸들러
@Override
@Async
public void asyncExceptionTest() {
int i=1/0;
}
모든 비동기 메서드를 try catch하지 않고도 Spring Async 프레임 워크를 사용하여 어떻게 로그 할 수 있습니까? 보통처럼 DefaultUncaughtExceptionHandler에 전달하지 않는 것 같습니다.
해결법
-
==============================
1.
@Configuration @EnableAsync public class ExampleConfig implements AsyncConfigurer { @Bean public Runnable testExec() { return new TestExec(); } @Override public Executor getAsyncExecutor() { final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.setThreadNamePrefix("MyExecutor-"); executor.initialize(); return new HandlingExecutor(executor); } } public class HandlingExecutor implements AsyncTaskExecutor { private AsyncTaskExecutor executor; public HandlingExecutor(AsyncTaskExecutor executor) { this.executor = executor; } @Override public void execute(Runnable task) { executor.execute(task); } @Override public void execute(Runnable task, long startTimeout) { executor.execute(createWrappedRunnable(task), startTimeout); } @Override public Future<?> submit(Runnable task) { return executor.submit(createWrappedRunnable(task)); } @Override public <T> Future<T> submit(final Callable<T> task) { return executor.submit(createCallable(task)); } private <T> Callable<T> createCallable(final Callable<T> task) { return new Callable<T>() { @Override public T call() throws Exception { try { return task.call(); } catch (Exception e) { handle(e); throw e; } } }; } private Runnable createWrappedRunnable(final Runnable task) { return new Runnable() { @Override public void run() { try { task.run(); } catch (Exception e) { handle(e); } } }; } private void handle(Exception e) { System.out.println("CAUGHT!"); } }
-
==============================
2.업데이트 : Spring 4.1부터
업데이트 : Spring 4.1부터
Spring 4.1부터 @Async void 메소드에 대해 AsyncUncaughtExceptionHandler를 사용할 수 있습니다.
Spring Reference Doc, @Async로 예외 관리하기
(이 기능은 DD가 impovement 요청을 제기 한 후에 소개되었습니다 : https://jira.spring.io/browse/SPR-8995,이 대답에 대한 설명 참조)
봄 4.1 이전
@Async 메서드를 반환하는 void 예외를 처리하는 방법이 누락 된 것처럼 보입니다. (참조 또는 java 문서에서 힌트를 찾을 수 없습니다.)
솔루션에 대해 상상할 수있는 것 : AspectJ를 사용하여 예외를 기록하는 모든 @Async 메서드를 구현하는 일종의 래퍼를 작성해보십시오.
로그 용어에 대해서는 스프링 버그 추적기에서 기능 요청을 작성하는 것이 좋습니다.
-
==============================
3.우선, 다음과 같이 사용자 정의 예외 핸들러 클래스를 작성해야합니다.
우선, 다음과 같이 사용자 정의 예외 핸들러 클래스를 작성해야합니다.
@Component public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { private final Logger logger = LoggerFactory.getLogger(AsyncExceptionHandler.class); @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { logger.error("Unexpected asynchronous exception at : " + method.getDeclaringClass().getName() + "." + method.getName(), ex); } }
그런 다음, 다음과 같이 구성에 사용자 정의 된 예외 핸들러 클래스를 설정해야합니다.
@Configuration @EnableAsync public class AsyncConfig extends AsyncConfigurerSupport { @Autowired private AsyncExceptionHandler asyncExceptionHandler; @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return asyncExceptionHandler; } }
참고 : 주사 가능한 예외 처리기는 옵션입니다. 모든 예외에 대해 새 인스턴스를 만들 수 있습니다. 스프링의 기본 범위가 싱글 톤이므로 모든 예외에 대해 새 인스턴스를 만들 필요가 없기 때문에 제 조언은 예외 처리기 클래스에 대한 주입을 사용합니다.
from https://stackoverflow.com/questions/8735870/spring-async-uncaught-exception-handler by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 보안 : 클라이언트 유형별 (브라우저 / 비 브라우저) CSRF 활성화 / 비활성화 (0) | 2019.03.14 |
---|---|
[SPRING] Spring이 자리 표시자를 해결할 수 없음 (0) | 2019.03.14 |
[SPRING] 봄에 상호 의존성 빈을 연결하는 방법? (0) | 2019.03.14 |
[SPRING] Spring의 BeanPostProcessor와 init / destroy 메소드의 차이점은 무엇입니까? (0) | 2019.03.13 |
[SPRING] Spring RedisTemplate : 여러 모델 클래스를 JSON으로 serialize합니다. 여러 RedisTemplates를 사용해야합니까? (0) | 2019.03.13 |