如何将异步作业附加到HTTP会话?

时间:2015-07-27 15:19:27

标签: java spring spring-mvc session asynchronous

我需要从控制器运行一些耗时的任务。为此,我在我的服务中实现了@Async方法,以便控制器可以立即返回(例如,202 Created状态)。

问题是该任务需要访问一些会话范围的bean。通过这种方法,我得到org.springframework.beans.factory.BeanCreationException: Error creating bean with name (...): Scope 'session' is not active for the current thread (...)

当我手动创建ExecutionService而不是@Async时,结果相同。

是否有可能以某种方式将工作线程附加到当前会话?

EDIT 目的是实现批量操作,提供监视处理状态的方法。这个回答中描述的内容:https://stackoverflow.com/a/28787774/718590

如果我同步运行它,将不会显示状态(处理了多少项),并且可能发生请求超时。

1 个答案:

答案 0 :(得分:1)

如果我正确理解,您希望能够从spring Web应用程序启动长时间的异步处理,并能够从启动它的会话中跟进处理的进展。处理可以使用会话中包含的bean。

为了很好地分离关注点,我永远不会让异步线程知道会话。该会话与HTTP相关,可以在线程完成(甚至在竞争条件下开始)处理之前随时销毁。

恕我直言,正确的设计是创建一个包含Web部件和异步处理之间共享的所有信息的类:状态(无论它是什么),开始处理的用户是否相关以及其他相关的一点信息。在您的控制器中(优先在控制器调用的服务方法中),您准备该类的对象,并将其传递给@Async方法。然后在返回之前,控制器将对象存储在会话中。那样:

  • 异步处理具有所有必需的信息,即使会话稍后被销毁。它不需要知道会话,只关心它的处理并更新其状态
  • Web应用程序的会话知道异步处理正在运行,知道它是如何启动的以及当前状态是什么

它可以适应您的真实问题,但这应该符合您的要求。