在Threads中访问作用域代理bean

Per*_*sh8 16 java spring spring-mvc threadpool

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

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

谢谢!

Eug*_*hov 47

我正在使用以下超类来完成需要访问请求范围的任务.基本上你可以扩展它并在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();
}
Run Code Online (Sandbox Code Playgroud)

  • 哇.我希望我可以再提高10票.谢谢您的帮助. (3认同)
  • 似乎这种方法有死锁,请参阅http://stackoverflow.com/q/15768556/438742 (2认同)

csa*_*uel 11

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

public abstract class RequestContextAwareCallable<V> implements Callable<V> {

    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;
}
Run Code Online (Sandbox Code Playgroud)