对会话范围的Springbean的外部线程回调



我有一个SpringWebMVC应用程序,在那里我需要使用一个外部设备驱动程序,每次设备收集一些新数据时,该驱动程序都会以异步方式返回信息。我们需要在乞求开始读取方法时传递一个对象。此对象实现了一个API定义的接口,该接口声明回调方法。

当这个回调方法需要在Spring的会话范围内操作一些bean时,问题就出现了。因为当回调实现想要访问Spring bean时,会在驱动程序的线程中调用回调,所以会产生一个异常,表明当前线程不在Spring的托管范围内。

我想知道是否有任何方法可以将实现回调接口的对象变成某种代理,该代理知道构建它的会话的上下文信息,这样它就可以通过Spring的上下文对象调用bean方法?

我认为你处理问题的角度不对。我想您希望设备驱动程序回调在用户会话中放入一些结果。但这还不足以显示数据,因此(再次猜测)可能涉及一些长时间的轮询,通过会话范围的bean查看会话。

根据这种假设,我建议您每次调用后端驱动程序并将requestId放入HTTP会话和回调中时,都生成某种唯一的requestId。当调用回调时,它会将结果推送到某种映射中,其中键是指定的requestId。现在,客户端(也知道requestId)可以查看映射并获取结果。您必须记住同步(正常HttpSession也是如此)。

如果您有一些更高级的通知客户端的方法(Comet?WebSockets?),也可以在这个回调中完成。

请注意,从技术上讲,您可以将HttpSession对象的实例传递到回调实例中(但正如您所看到的,这不适用于Spring会话范围的bean),但传递会话似乎不是一个好的设计。提供一定程度的间接性会更好。如果将来您想在命令行或桌面客户端中重用这些代码,该怎么办?

最新更新