我曾在一个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
最佳答案
我在几个项目中看到它,用于存储一些基础设施项目(例如用户唯一标识符,以跟踪特定 session 的日志消息。
必须小心处理,因为如果您的代码在 Java EE 服务器上运行,线程将被合并并重新用于其他 session 。如果您不重置 ThreadLocal 状态,您最终会遇到意外数据干扰的麻烦(就像在一个线程运行值中对应一个较旧的运行)。
所以,在你的代码中我错过了这个方法:
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();
}
}
关于java - 以下技术获取 RequestContext 是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4085549/