我想要实现的是,通过以这种简单的方式使用多线程,在我的 RESTApi 控制器中使用 @Async 和 CompletableFuture 可以获得更好的性能吗?
这是我所做的,这是我的控制器:
@PostMapping("/store")
@Async
public CompletableFuture<ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>>> saveNewCategoryBPSJ(@Valid @RequestBody InputRequest<CategoryBPSJRequestDto> request) {
CompletableFuture<ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>>> future = new CompletableFuture<>();
future.complete(ResponseEntity.ok(new ResponseRequest<>("Okay", categoryBPSJService.save(request))));
return future;
}
Run Code Online (Sandbox Code Playgroud)
VS
@PostMapping("/store")
public ResponseEntity<ResponseRequest<CategoryBpsjResponseDto>> saveNewCategoryBPSJ(@Valid @RequestBody InputRequest<CategoryBPSJRequestDto> request) {
return ResponseEntity.ok(new ResponseRequest<>("okay", categoryBPSJService.save(request));
}
Run Code Online (Sandbox Code Playgroud)
正如你在我的第一个控制器函数中看到的,我在我的函数响应中添加了 CompletableFuture,但是在我的服务中,我在这一行中保存的categoryBPSJService.save(request)不是异步的,只是一个看起来像这样的简单函数:
public CategoryBpsjResponseDto save(InputRequest<CategoryBPSJRequestDto> request) {
CategoryBPSJRequestDto categoryBPSJDto = request.getObject();
Boolean result = categoryBPSJRepository.existsCategoryBPSJBycategoryBPSJName(categoryBPSJDto.getCategoryBPSJName());
if(result){
throw new ResourceAlreadyExistException("Category BPSJ "+ categoryBPSJDto.getCategoryBPSJName() + " already exists!");
}
CategoryBPSJ categoryBPSJ = new CategoryBPSJ();
categoryBPSJ = map.DTOEntity(categoryBPSJDto);
categoryBPSJ.setId(0L); …Run Code Online (Sandbox Code Playgroud) 我面临一个问题,因为我启用了将同步方法转换为异步方法:如果从方法体内抛出异常,我就不能再重新抛出它了.
让我先展示代码:
我的异步/任务执行器配置:
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
}
Run Code Online (Sandbox Code Playgroud)
我的异步方法:
@Async
@Override
public void sendPasswordResetInfo(String email) {
Assert.hasText(email);
Member member = memberRepository.findByEmail(email);
try {
mailerService.doMailPasswordResetInfo(member);//EXCEPTION THROWN HERE
} catch (MessagingException | MailSendException e) {
log.error("MessagingException | MailSendException", e);
// TODO: not thrown since @Async is used
throw new MailerException("MessagingException | MailSendException");//NOT CALLED
}
}
Run Code Online (Sandbox Code Playgroud)
我mailerService.doMailPasswordResetInfo引用异常时在控制台中看到的是以下堆栈跟踪:
2014-06-20 18:46:29,249 [ThreadPoolTaskExecutor-1] …Run Code Online (Sandbox Code Playgroud)