Struts2源码阅读(二)_ActionContext及CleanUP Filter
1. ActionContext
ActionContext是被存放在當前線程中的,獲取ActionContext也是從ThreadLocal中獲取的。所以在執行攔截器、 action和result的過程中,由于他們都是在一個線程中按照順序執行的,所以可以可以在任意時候在ThreadLocal中獲取 ActionContext。
ActionContext包括了很多信息,比如Session、Application、Request、Locale、ValueStack等,其中 ValueStack可以解析ognl表達式,來動態后去一些值,同時可以給表達式提供對象。
?
ActionContext(com.opensymphony.xwork.ActionContext)是Action執行時的上下文,上下文可以看作是一個容器 (其實我們這里的容器就是一個Map而已),它存放的是Action在執行時需要用到的對象. 一般情況, 我們的ActionContext都是通過: ActionContext context = (ActionContext) actionContext.get(); 來獲取的.我們再來看看這里的actionContext對象的創建:
static ThreadLocal actionContext = new ActionContextThreadLocal();
ActionContextThreadLocal是實現ThreadLocal的一個內部類.ThreadLocal可以命名為"線程局部變量",它為每一個使用該變量的線程都提供一個變量值的副本,使每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突.這樣,我們 ActionContext里的屬性只會在對應的當前請求線程中可見,從而保證它是線程安全的.
通過ActionContext取得HttpSession: Map session = ActionContext.getContext().getSession(); (通過Map模擬HttpServlet的對象,操作更方便)
?
2. ServletActionContext
ServletActionContext(com.opensymphony.webwork. ServletActionContext),這個類直接繼承了我們上面介紹的ActionContext,它提供了直接與Servlet相關對象訪問的功能,它可以取得的對象有:
(1)javax.servlet.http.HttpServletRequest : HTTPservlet請求對象?
(2)javax.servlet.http.HttpServletResponse : HTTPservlet相應對象?
(3)javax.servlet.ServletContext : Servlet上下文信息?
(4)javax.servlet.ServletConfig : Servlet配置對象?
(5)javax.servlet.jsp.PageContext : Http頁面上下文
如何從ServletActionContext里取得Servlet的相關對象:
<1>取得HttpServletRequest對象: HttpServletRequest request = ServletActionContext. getRequest();
<2>取得HttpSession對象: HttpSession session = ServletActionContext. getRequest().getSession();
?
3. ServletActionContext和ActionContext聯系
ServletActionContext和ActionContext有著一些重復的功能,在我們的Action中,該如何去抉擇呢?我們遵循的原則是:如果ActionContext能夠實現我們的功能,那最好就不要使用ServletActionContext,讓我們的Action盡量不要直接去訪問Servlet的相關對象.
注意:在使用ActionContext時有一點要注意: 不要在Action的構造函數里使用ActionContext.getContext(), 因為這個時候ActionContext里的一些值也許沒有設置,這時通過ActionContext取得的值也許是null;同樣,HttpServletRequest req = ServletActionContext.getRequest()也不要放在構造函數中,也不要直接將req作為類變量給其賦值。 至于原因,我想是因為前面講到的static ThreadLocal actionContext = new ActionContextThreadLocal(),從這里我們可以看出ActionContext是線程安全的,而 ServletActionContext繼承自ActionContext,所以ServletActionContext也線程安全,線程安全要求每個線程都獨立進行,所以req的創建也要求獨立進行,所以ServletActionContext.getRequest()這句話不要放在構造函數中,也不要直接放在類中,而應該放在每個具體的方法體中(eg:login()、queryAll()、insert()等),這樣才能保證每次產生對象時獨立的建立了一個req。
?
4.ActionContextClearUp
ActionContextClearUp其實是Defer ClearUP.作用就是延長action中屬性的生命周期,包括自定義屬性,以便在jsp頁面中進行訪問,讓actionContextcleanup過濾器來清除屬性,不讓action自己清除。具體看下面的代碼,代碼很簡單:
public void doFilter(...){ ... try{ ... //繼續執行所配置的chain中的Filter chain.doFilter(request, response); }finally{ //保證在所有動作執行完之后,調用cleanUp ... cleanUp(request); } } protected static void cleanUp(ServletRequest req) { ... ActionContext.setContext(null);//清除ActionContext實例 Dispatcher.setInstance(null);//清除Dispatcher實例(Dispatcher主要是完成將url解析成對應的Action) } 另外注明一下UtilTimerStack的push和pop是用來計算調用方法所執行的開始和結束時間,用來做性能測試的。用法如下:
String timerKey = "ActionContextCleanUp_doFilter: "; UtilTimerStack.setActive(true); UtilTimerStack.push(timerKey); //調用要測試的方法。 UtilTimerStack.pop(timerKey);
總結
以上是生活随笔為你收集整理的Struts2源码阅读(二)_ActionContext及CleanUP Filter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Data JPA 从入门到
- 下一篇: Java消息服务~自动分配的消息头