以下技术是否正确获取RequestContext

时间:2010-11-03 09:16:17

标签: java java-ee

我在J2EE项目中看到了以下代码。

public class RequestContext {
    private final static ThreadLocal<RequestContext> contexts = new ThreadLocal<RequestContext>();

    /* Initialization */
    public static RequestContext begin(ServletContext ctx, HttpServletRequest req, HttpServletResponse res) {
        RequestContext rc = new RequestContext();
        ..
        contexts.set(rc);
        return rc;
    }

    public static RequestContext get(){
        return contexts.get();
    }
}

看来通过ThreadLocal和静态get,我们可以轻松获取当前线程的当前RequestContext。

但是,这是一种常见做法吗?这是一种正确的方法吗?是否有可能发生内存泄漏?

Why the object created by ClassLoader do not have chance to garbage collect itself

1 个答案:

答案 0 :(得分:2)

我在一些项目中看到过它,用于存储一些基础设施项目(例如用户唯一标识符),以跟踪特定会话的日志消息。

必须小心处理,因为如果您的代码在Java EE服务器上运行,则将汇集线程并将其重用于其他会话。如果你没有重置ThreadLocal状态,你最终会遇到意外数据干扰的麻烦(比如在一个Thread运行中的值与旧运行相对应)。

所以,在你的代码中我想念这个方法:

public static void reset() {
   contexts.remove();
}

诅咒,它必须在某处使用:通常在初始化它的同一个地方(也许是WebApp过滤器?)

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
  throws IOException, ServletException {

      RequestContext.begin(ctx, request, response); //initialize
      try {
         //other stuff here

         //forward request to next filter, or the servlet itself
         chain.doFilter(request, response);
      } finally {   
         RequestContext.reset();
      }
}