本文介绍了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时,异常处理不正确。

It works great most of the time but when the NotCachedException is thrown from a method annotated with @Async, the exception is not handled properly.

@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);
}

这是执行者的配置:

@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带注释的方法吗?

What can I do in order to make it work with @Async annotated methods?

推荐答案

默认的异常处理机制在启用@Async的情况下不起作用。
要处理从@Async注释的方法抛出的异常,您需要将自定义的AsyncExceptionHandler实现为。

The default exception handling machenism does not work in case of @Async Enabled.To handle exception thrown from methods annotated with @Async, you need to implement a custom AsyncExceptionHandler as.

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

    }
}

现在需要配置此customExceptionHandler在您的应用程序类中

Now You need to configure this customExceptionHandler in you Application class as

@EnableAsync
public class Application implements AsyncConfigurer {
     @Override Executor getAsyncExecutor(){
      // your ThreadPoolTaskExecutor configuration goes here.
}


@Override
public AsyncUncaughExceptionHandler getAsyncUncaughtExceptionHandler(){
   return new AsyncExceptionHandler();
}

注意:确保为了使AsyncExceptionHandler工作,您需要实现AsyncConfigurer在你的应用程序类中。

Note: Make sure in order to make your AsyncExceptionHandler work you need to implement AsyncConfigurer in your Application class.

这篇关于Spring @ExceptionHandler和多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:53