2015-05-18 51 views
3

我在解決如何正確處理JSF中會話的自動銷燬時遇到了問題。當然,在這個時候,會話會被容器取消,導致在會話作用域bean上調用@PreDestroy方法。在會話超時時刪除JSF託管的bean

在一些會議PreDestroy範圍的Bean,我們註銷了一些聽衆,象下面這樣:

@PreDestroy 
public void destroy() { 
    getWS().removeLanguageChangeListener(this); 
} 

然而,getWS()方法實際上是試圖去作用域的bean另一個會話的參考,但失敗,因爲FacesContext.getCurrentInstance()返回null。 根據Ryan Lubke的說法,後者似乎是正常的JSF行爲:

我們對此處的規範信守承諾。我不確定假設 可以安全地使FacesContext在所有@PreDestroy情況下都可用。 考慮會話範圍的bean。由於不活動,會話可能會由 容器超時。 FacesContext當時不可用於 。

對我很好,但是如何確保所有對象都被正確清除?在PreDestroy中將自己作爲偵聽器移除是不好的做法嗎? 或者我們只需要爲請求/視圖範圍的bean執行此操作,因爲它們的活動時間比WS的會話範圍(從getWS())長?

請注意,我在Tomcat7上得到這種行爲,但我期望這個問題發生在每個容器上。

回答

1

我認爲會話bean在servlet容器的專用線程中被清除,因此不在FacesContext(它與JSF請求相關聯)之外。您可以使用HttpSessionListener來解決問題並清理會話資源。喜歡的東西:

@WebListener 
public class LifetimeHttpSessionListener implements HttpSessionListener { 

@Override 
public void sessionCreated(final HttpSessionEvent e) { 
    // create some instance here and save it in HttpSession map 
    HttpSession session = e.getSession(); 
    session.setAttribute("some_key", someInstance); 
    // or elsewhere in JSF context: 
    // FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("some_key", someInstance); 
} 

@Override 
public void sessionDestroyed(final HttpSessionEvent e) { 
    // get resources and cleanup them here 
    HttpSession session = e.getSession(); 
    Object someInstance = session.getAttribute("some_key"); 
} 
} 

希望這能爲你

有幫助