복붙노트

[SPRING] Spring @ExceptionHandler 및 멀티 스레딩

SPRING

Spring @ExceptionHandler 및 멀티 스레딩

다음과 같은 컨트롤러 조언이 있습니다.

@ControllerAdvice
public class ExceptionHandlerAdvice {

    @ExceptionHandler(NotCachedException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ModelAndView handleNotCachedException(NotCachedException ex) {
        LOGGER.warn("NotCachedException: ", ex);
        return generateModelViewError(ex.getMessage());
    }

}

대부분의 경우 잘 작동하지만, @Async로 주석 된 메소드에서 NotCachedException이 발생하면 예외가 제대로 처리되지 않습니다.

@RequestMapping(path = "", method = RequestMethod.PUT)
@Async
public ResponseEntity<String> store(@Valid @RequestBody FeedbackRequest request, String clientSource) {
    cachingService.storeFeedback(request, ClientSource.from(clientSource));
    return new ResponseEntity<>(OK);
}

다음은 Executor의 구성입니다.

@SpringBootApplication
@EnableAsync
public class Application {

private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        SettingsConfig settings = context.getBean(SettingsConfig.class);
        LOGGER.info("{} ({}) started", settings.getArtifact(), settings.getVersion());
        createCachingIndex(cachingService);
    }

    @Bean(name = "matchingStoreExecutor")
    public Executor getAsyncExecutor() {
        int nbThreadPool = 5;
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(nbThreadPool);
        executor.setMaxPoolSize(nbThreadPool * 2);
        executor.setQueueCapacity(nbThreadPool * 10);
        executor.setThreadNamePrefix("matching-store-executor-");
        executor.initialize();
        return executor;
    }

}

@Async 주석이 달린 메서드를 사용하려면 어떻게해야합니까?

해결법

  1. ==============================

    1.@Async Enabled의 경우 기본 예외 처리 기능이 작동하지 않습니다. @Async로 주석 된 메소드에서 Throw 된 예외를 처리하려면 사용자 정의 AsyncExceptionHandler를 as로 구현해야합니다.

    @Async Enabled의 경우 기본 예외 처리 기능이 작동하지 않습니다. @Async로 주석 된 메소드에서 Throw 된 예외를 처리하려면 사용자 정의 AsyncExceptionHandler를 as로 구현해야합니다.

    public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler{
        @Override
        public void handleUncaughtException(Throwable ex, Method method, Object... params) {
            // Here goes your exception handling logic.
    
        }
    }
    

    이제이 customExceptionHandler를 응용 프로그램 클래스에서 다음과 같이 구성해야합니다.

    @EnableAsync
    public class Application implements AsyncConfigurer {
         @Override Executor getAsyncExecutor(){
          // your ThreadPoolTaskExecutor configuration goes here. 
    }
    
    
    @Override
    public AsyncUncaughExceptionHandler getAsyncUncaughtExceptionHandler(){
       return new AsyncExceptionHandler();
    }
    

    참고 : AsyncExceptionHandler를 작동 시키려면 Application 클래스에 AsyncConfigurer를 구현해야합니다.

  2. from https://stackoverflow.com/questions/44138199/spring-exceptionhandler-and-multi-threading by cc-by-sa and MIT license