从@Async函数调用中获取数据

问题描述 投票:0回答:3

嗨,我是 java 多线程的新手。有人可以帮我解决这个问题吗:

我的服务:

@Async
public List<String> doSomething(int a){
    //Do something
    return list;
}

Springboot应用:

@SpringBootApplication
@EnableAsync
public class Test {

    public static void main(String[] args) {
        SpringApplication.run(Test.class, args);
    }

}

异步配置:

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name ="taskExecutor")
    public Executor taskExecutor(){
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("userThread-");
        executor.initialize();
        return executor;
    }
}

控制器:

@RestController
public class Controller{
    
    @Autowired
    private Service service;

    @GetMapping("test")
    public List<String> getAll(){
        return service.doSomething(1);
    }
}

当我点击邮递员的此获取请求时,它在响应中显示为空白。我知道我的调用是异步进行的,甚至在调用我的方法之前响应就会返回。有没有办法通过更改我的邮递员或 Spring Boot 应用程序中的某些设置来查看此响应

java spring spring-boot spring-mvc asynchronous
3个回答
3
投票

如果你想异步处理请求,但又希望API客户端在处理完成后收到响应,这样从客户端的角度来看,请求处理仍然看起来像同步的,关键是使用Servlet3异步处理功能。

您无需使用

@Aysnc
将其配置为在服务级别异步执行。相反,将控制器方法配置为返回
CompletableFuture
。在幕后,它将触发 Servlet3 的异步请求处理,该处理将在接收请求的 HTTP 线程之外的另一个线程中处理该请求。

所以你的代码应该类似于:

public class Service {
    
    //No need to add @Async
    public List<String> doSomething(int a){
        return list;
    }
}


@RestController
public class Controller{
    
    @Autowired
    private Service service;

    @GetMapping("test")
    public CompletableFuture<List<String>> getAll(){
        return CompletableFuture.supplyAsync(()->service.doSomething(1));
    }
}

关于 spring-mvc 支持的 Servlet3 异步请求处理的详细内容,可以参考从this开始的这个博客系列。


1
投票

如果您想使用异步,我会将您的单个请求拆分为所谓的“启动任务”和“获取任务结果”请求。您的应用程序返回“启动任务”请求的“请求 ID”。然后在执行“获取任务结果”时使用“请求 ID”。这样的场景是批处理任务中常见的方式。如果您使用 Spring,您可能会对研究 Spring Batch 框架感兴趣,该框架具有启动/停止/重新启动作业功能等。


1
投票

您可以返回CompletableFuture。当 CompleteableFuture 完成时,您将收到 http 响应。

服务:

@Async
public CompletableFuture<List<String>> doSomething() {
    return CompletableFuture.completedFuture(Arrays.asList("1", "2", "3"));
} 

控制器:

@GetMapping("test")
public CompletableFuture<List<String>> getAll(){
    return service.doSomething();
}
© www.soinside.com 2019 - 2024. All rights reserved.