在Threads中访问作用域代理bean

我有一个在tomcat中运行的Web应用程序,我正在使用ThreadPool(Java 5 ExecutorService)并行运行IO密集型操作以提高性能。 我想让每个池化线程中使用的一些bean都在请求范围内,但ThreadPool中的Threads无法访问spring上下文并获得代理失败。 关于如何使用ThreadPool中的线程可以使弹簧上下文可用来解决代理失败的任何想法?

我猜测必须有一种方法来注册/取消注册ThreadPool中的每个线程,每个任务都有spring,但是没有任何运气找到如何做到这一点。

谢谢!

我正在使用以下超类来完成需要访问请求范围的任务。 基本上你可以扩展它并在onRun()方法中实现你的逻辑。

import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; /** * @author Eugene Kuleshov */ public abstract class RequestAwareRunnable implements Runnable { private final RequestAttributes requestAttributes; private Thread thread; public RequestAwareRunnable() { this.requestAttributes = RequestContextHolder.getRequestAttributes(); this.thread = Thread.currentThread(); } public void run() { try { RequestContextHolder.setRequestAttributes(requestAttributes); onRun(); } finally { if (Thread.currentThread() != thread) { RequestContextHolder.resetRequestAttributes(); } thread = null; } } protected abstract void onRun(); } 

我也希望我有1000票可以给出目前接受的答案。 一段时间以来,我一直难以理解如何做到这一点。 基于它,这是我使用Callable接口的解决方案,以防你想在Spring 3.0中使用一些新的@Async东西。

 public abstract class RequestContextAwareCallable implements Callable { private final RequestAttributes requestAttributes; private Thread thread; public RequestContextAwareCallable() { this.requestAttributes = RequestContextHolder.getRequestAttributes(); this.thread = Thread.currentThread(); } public V call() throws Exception { try { RequestContextHolder.setRequestAttributes(requestAttributes); return onCall(); } finally { if (Thread.currentThread() != thread) { RequestContextHolder.resetRequestAttributes(); } thread = null; } } public abstract V onCall() throws Exception; } 

你可以反过来试试吗? 使用存储在请求范围中的数据容器并将其提供给线程池(可能将其放入队列中,以便线程池一次可以占用一个数据容器,对其进行处理,将其标记为“已完成”并继续与下一个)。

Spring有一个ThreadPoolTask​​Executor类,您可以使用它来管理Spring的线程池。 但是,看起来您必须做一些工作才能使每个线程都可以使用Spring上下文。

我不确定它是否会起作用,即使你以这种方式连线也是如此。 Spring在本地线程中使用一个令牌来定位请求(或会话)范围内的对象,因此如果您尝试从另一个线程访问请求范围bean,则很可能该令牌不在那里。