Struts2源碼閱讀(二)_ActionContext及CleanUP Filter

來源:互聯網
上載者:User

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(...){ </p><p> ...<br /> try{<br /> ...<br /> //繼續執行所配置的chain中的Filter<br /> chain.doFilter(request, response);<br /> }finally{<br /> //保證在所有動作執行完之後,調用cleanUp<br /> ...<br /> cleanUp(request);<br /> }<br />} </p><p>protected static void cleanUp(ServletRequest req) { </p><p> ...<br /> ActionContext.setContext(null);//清除ActionContext執行個體<br /> Dispatcher.setInstance(null);//清除Dispatcher執行個體(Dispatcher主要是完成將url解析成對應的Action)<br />}<br />

另外註明一下UtilTimerStack的push和pop是用來計算調用方法所執行的開始和結束時間,用來做效能測試的。用法如下:

String timerKey = "ActionContextCleanUp_doFilter: "; </p><p>UtilTimerStack.setActive(true); </p><p>UtilTimerStack.push(timerKey);<br />//調用要測試的方法。<br />UtilTimerStack.pop(timerKey);

Come From: http://qidaoxp.javaeye.com/blog/492387

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.