2010-11-03 89 views
2

我在J2EE項目中看到了以下代碼。以下技術是否正確獲取RequestContext

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

回答

2

我已經看到它在幾個項目,用於存儲一些基礎設施項目(如用戶唯一的標識符,跟蹤日誌消息一定會。

它必須與被移交因爲如果您的代碼在Java EE服務器上運行,則線程將被集中並重用於其他會話。如果您未重置ThreadLocal狀態,則最終會遇到意外數據干擾的問題(如在在一個線程運行值對應一個較舊的運行)

因此,在您的代碼我想這個方法:

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

詛咒,就必須使用的地方:通常在您初始化同一個地方(可能是一個Web應用程序過濾器?)

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(); 
     } 
}