如何在 Spring 引导中创建部分异步 post 请求?

How to create partly async post request in Spring boot?

我是 Spring Boot 的新手,我想创建一种异步请求。它应该允许用户上传文件。然后 Spring 应用程序应该保存它并回答用户文件已正确保存。

然后整个异步部分发生了。服务器应该在保存文件后立即开始处理文件(在后台)。目前,它不会 运行 在后台(用户需要等到 processFileInBackground 完成):

控制器:

@CrossOrigin
@RestController
public class ProcessFileController {
    @Autowired
    ProcessFileService processFileService;

    @CrossOrigin
    @PostMapping("/files/upload")
    public ResponseEntity<String> singleFileUpload(@RequestParam("file") MultipartFile file) {
        System.out.println("singleFileUpload tid: " + Thread.currentThread().getId());
        bytes = file.getBytes();
        // Save file...
        String plainText = new String(bytes, StandardCharsets.UTF_8);
        processFileInBackground(plainText);
        return new ResponseEntity<>("File successfully uploaded!", HttpStatus.OK);
    }


    private void processFileInBackground(String plainText) {
        processFileService = new ProcessFileService(plainText);
        String result = processFileService.getResult();
    }
}

服务:

@Service
public class ProcessFileService {

    private FileProcessor fileProcessor;

    public CompilerApiService(String plainText){
        fileProcessor = new FileProcessor(code);
    }

    @Async
    public String getResult(){
        System.out.println("getResult tid: " + Thread.currentThread().getId());
        // The call below takes a long time to finish
       return fileProcessor.getResult();
    }

}

配置:

@EnableAsync
@Configuration
public class AsyncConfig {
    @Bean
    public Executor threadPoolTaskExecutor() {
        return new ConcurrentTaskExecutor(Executors.newCachedThreadPool());
    }
}

Spring 为您提供 @Async 注解,您需要将您的异步逻辑分离到一个单独的 class 中,并使用此异步注解您的方法,这将在单独的线程中执行您的逻辑。 检查这个 https://spring.io/guides/gs/async-method/

请注意,您必须从调用者外部调用异步方法 class 才能在异步模式下执行,如下所示

@CrossOrigin
@RestController
public class ProcessFileController {
    @Autowired
    ProcessFileService processFileService;

    @CrossOrigin
    @PostMapping("/files/upload")
    public ResponseEntity<String> singleFileUpload(@RequestParam("file") MultipartFile file) {
        bytes = file.getBytes();
        // Save file...
        String plainText = new String(bytes, StandardCharsets.UTF_8);
        processFileInBackground(plainText);
        return new ResponseEntity<>("File successfully uploaded!", HttpStatus.OK);
    }


    private void processFileInBackground(String plainText) {
        processFileService = new ProcessFileService(plainText);
        String result = processFileService.getResult();
    }
}

服务

@Service
public class ProcessFileService {

    private FileProcessor fileProcessor;

    public CompilerApiService(String plainText){
        fileProcessor = new FileProcessor(code);
    }

    @Async
    public String getResult(){
       return fileProcessor.getResult();
    }

}

配置

@EnableAsync
@Configuration
public class AsyncConfig {
    @Bean(name = "threadPoolExecutor")
    public Executor getAsyncExecutor() {
      ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
      executor.setCorePoolSize(7);
      executor.setMaxPoolSize(42);
      executor.setQueueCapacity(11);
      executor.setThreadNamePrefix("threadPoolExecutor-");
      executor.initialize();
      return executor;
    }
}