I had seen the following code in a J2EE project.
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();
}
}
It seems that by having ThreadLocal
and a static get
, we w开发者_开发技巧ill have an easy way to obtain the current RequestContext of current thread.
But, is this a common practice? Is it a correct way to do so? Is there a chance of having memory leak?
Why the object created by ClassLoader do not have chance to garbage collect itself
I have seen it at a few projects, for storing some infrastructure items (such as a user unique identifier, to trace the log messages for a certain session.
It must be handed with care, because if your code is running on a Java EE server, the Threads will be pooled and reused for other sessions. If you don't reset the ThreadLocal state, you'll end up having troubles with unexpected data interfering (as in having in one Thread run values corresponding an older run).
So, at your code I miss this method:
public static void reset() {
contexts.remove();
}
Of curse, it must be used somewhere: usually at the same place where you initialize it (perhaps a WebApp Filter?)
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();
}
}
精彩评论