相关疑难解决方法(0)

在控制器中使用 @Async 和 CompletableFuture 可以提高我们 api 的性能吗?

我想要实现的是,通过以这种简单的方式使用多线程,在我的 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)

java performance spring asynchronous completable-future

12
推荐指数
1
解决办法
1279
查看次数

Spring @Async方法没有捕获/重新抛出异常的问题

我面临一个问题,因为我启用了将同步方法转换为异步方法:如果从方法体内抛出异常,我就不能再重新抛出它了.

让我先展示代码:

我的异步/任务执行器配置:

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

spring asynchronous

3
推荐指数
1
解决办法
1万
查看次数