struts2值棧內部數據結構詳解


  值棧是struts2內部一片很重要的區域,我在初學的時候,發現對於值棧這個數據結構的理解不是很深刻.例如OGNLContext是什么,ActionContext和值棧有什么關系.為什么ActionContext可以獲得值棧和contextMap等等,這些都是在我初學的時候的難以理解的概念性問題.我在網上查找了很多資料,發現網上對於這一概念的解釋很多都是復制粘貼或者解釋的不是很清楚,因此寫一篇博文幫助和我一樣對於struts2值棧內部的數據結構的引用不清楚的童鞋!首先看看值棧的數據結構:

  可以看出OgnlValueStack(值棧的實現類)包含兩大部分:CompoundRoot(這其實是一個ArrayList.)和context.(我們通常稱為contextMap).有了這個知識儲備,接下來我們去看struts2關於值棧創建的源碼:

  在學習中,我們知道.值棧是和ActionContext同步創建的.因此需要了解值棧的創建,必須要進入ActionContext的創建方法里去觀察.實際上,在struts2的核心過濾器StrutsPrepareAndExecuteFilter里在每次請求都會調用的doFilter方法里很容易就能找到這個方法.

  進入到這個方法的內部觀察,我們可以獲得很多的信息.

  整個過程分為4步,首先我們進入第一步(標注為1的代碼)的方法內部,觀察值棧的創建.

  可以看出在struts2中值棧的實現類是OgnlValueStack.繼續進入構造方法內部觀察:

  可以看出contextMap內部是維護了值棧的引用的.進入createDefaultContext方法內部:

  

  從標志的這一句可以看出來contextMap內部也維護了root的引用.至此,我們知道,在這時,值棧已經創建完畢.且值棧的contextMap內部維護了值棧本身(OgnlValueStack)以及根(ComponentRoot)的引用.實際上,也可以看出來值棧的contextMap的實際數據結構為OgnlContext.接下來我們跟蹤在PreparedOperations類內部createActionContext方法的stack.getContext().putAll這一句(上面標注的第二步).直接進入dispatcher.createContextMap的內部.

  可以看出這個操作,就是在contextMap內部加入了各個域對象(request,ServletContext,session)的引用.通過contextMap可以獲取到各個域對象的引用.

  返回,在createActionContext方法內,繼續往下走,第三步,可以看出將值棧(OgnlValueStack)的contextMap作為ActionContext的構造方法的參數傳了進去.進入ActionContext類,實際上其內部是維護了一個叫做context的map來指向OgnlValueStack的contextMap的.而構造方法,正是對這個叫做context的成員變量初始化賦值.

  實際上,ActionContext獲取值棧.獲取contextMap.獲取Servlet相關的API都是通過這個context來實現的:

  返回createActionContext方法,進入第四步.也就是ActionContext.setContext()方法.這個方法將新建的ActionContext以靜態方法的參數傳入ActionContext.進入這個方法內部:

  

  原來這個方法是將新創建的ActionContext綁定到了ThreadLocal上.ThreadLocal的set方法是將ThreadLocal對象和數據對象作為鍵值對存入線程對象內部的一個Map類型的數據結構里.因此,由於ActionContext被綁定在ThreadLocal對象上,所以ActionContext是線程安全的.

  綜上,這就是值棧的創建過程.可以看出ActionContext和值棧同時創建,而且都是一次請求創建一次.生命周期為1次請求!值棧包括兩部分:contextMap和root.其中contextMap維護了值棧本身和root的引用.ActionContext內部維護了contextMap的引用,因此一些教程上說的,ActionContext內部維護了值棧的引用是不正確的!正確的說法應該是ActionContext內部維護了contextMap的引用,contextMap內部維護了值棧的引用!為了便於理解,我畫出了下面的圖,僅供參考: 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM