You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot运行时无法获取所有请求作用域Bean,异步请求挂起问题

问题分析与解决方案

核心问题根源

你用@RequestScope的思路完全错了——请求作用域的Bean是和单个HTTP请求上下文绑定的:

  • 每个/future请求都会创建专属的FutureManager实例,这个实例只存在于当前请求的上下文(RequestAttributes)中
  • 当你调用/complete时,这个请求有自己独立的上下文,通过ApplicationContext.getBeansOfType只能拿到当前/complete请求自己生成的FutureManager实例,根本访问不到前两个/future请求的实例。日志里的第三个实例就是/complete请求自己创建的,和前两个毫无关系。

正确实现方案

需要用一个全局的线程安全容器来管理所有待完成的CompletableFuture,而不是依赖请求作用域。以下是修正后的代码:

1. 重构FutureManager为单例服务

@Service
class FutureManager {
    // 使用线程安全的集合存储所有待完成的Future
    private val pendingFutures = CopyOnWriteArrayList<CompletableFuture<Boolean>>()

    fun complete(value: Boolean) {
        // 完成所有待处理的Future
        pendingFutures.forEach { it.complete(value) }
        // 清理已完成的Future,避免内存泄漏
        pendingFutures.removeIf { it.isDone }
    }

    fun get(): Boolean {
        val future = CompletableFuture<Boolean>()
        pendingFutures.add(future)
        // 注册回调:Future完成(无论成功/失败)时自动从集合移除
        future.whenComplete { _, _ -> pendingFutures.remove(future) }
        return future.get()
    }
}

2. 简化控制器实现

不需要再通过ApplicationContext查找Bean,直接注入单例的FutureManager即可:

@RestController
class FutureController(
    private val manager: FutureManager
) {
    @GetMapping("/future")
    fun getFuture(): Boolean {
        println("New client waiting for value")
        return manager.get()
    }
}

@RestController
class CompleteFutureController(
    private val manager: FutureManager
) {
    @GetMapping("/complete")
    fun completeFuture(@RequestParam value: Boolean) {
        manager.complete(value)
        println("Completed all pending futures with value: $value")
    }
}

关键细节说明

  • CopyOnWriteArrayList保证了多线程下遍历、添加、移除操作的线程安全,适合这种读多写少的场景
  • 加入whenComplete回调是为了防止内存泄漏:如果某个/future请求超时或异常结束,对应的Future会自动从集合中移除
  • 如果需要支持按不同主题分发消息,可以把集合改成ConcurrentHashMap<String, List<CompletableFuture<Boolean>>>,用主题作为key实现分组通知

内容的提问来源于stack exchange,提问作者J.Kennsy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:58:12