struts2值栈内部数据结构详解
值棧是struts2內(nèi)部一片很重要的區(qū)域,我在初學(xué)的時(shí)候,發(fā)現(xiàn)對(duì)于值棧這個(gè)數(shù)據(jù)結(jié)構(gòu)的理解不是很深刻.例如OGNLContext是什么,ActionContext和值棧有什么關(guān)系.為什么ActionContext可以獲得值棧和contextMap等等,這些都是在我初學(xué)的時(shí)候的難以理解的概念性問(wèn)題.我在網(wǎng)上查找了很多資料,發(fā)現(xiàn)網(wǎng)上對(duì)于這一概念的解釋很多都是復(fù)制粘貼或者解釋的不是很清楚,因此寫一篇博文幫助和我一樣對(duì)于struts2值棧內(nèi)部的數(shù)據(jù)結(jié)構(gòu)的引用不清楚的童鞋!首先看看值棧的數(shù)據(jù)結(jié)構(gòu):
可以看出OgnlValueStack(值棧的實(shí)現(xiàn)類)包含兩大部分:CompoundRoot(這其實(shí)是一個(gè)ArrayList.)和context.(我們通常稱為contextMap).有了這個(gè)知識(shí)儲(chǔ)備,接下來(lái)我們?nèi)タ磗truts2關(guān)于值棧創(chuàng)建的源碼:
在學(xué)習(xí)中,我們知道.值棧是和ActionContext同步創(chuàng)建的.因此需要了解值棧的創(chuàng)建,必須要進(jìn)入ActionContext的創(chuàng)建方法里去觀察.實(shí)際上,在struts2的核心過(guò)濾器StrutsPrepareAndExecuteFilter里在每次請(qǐng)求都會(huì)調(diào)用的doFilter方法里很容易就能找到這個(gè)方法.
進(jìn)入到這個(gè)方法的內(nèi)部觀察,我們可以獲得很多的信息.
整個(gè)過(guò)程分為4步,首先我們進(jìn)入第一步(標(biāo)注為1的代碼)的方法內(nèi)部,觀察值棧的創(chuàng)建.
可以看出在struts2中值棧的實(shí)現(xiàn)類是OgnlValueStack.繼續(xù)進(jìn)入構(gòu)造方法內(nèi)部觀察:
可以看出contextMap內(nèi)部是維護(hù)了值棧的引用的.進(jìn)入createDefaultContext方法內(nèi)部:
從標(biāo)志的這一句可以看出來(lái)contextMap內(nèi)部也維護(hù)了root的引用.至此,我們知道,在這時(shí),值棧已經(jīng)創(chuàng)建完畢.且值棧的contextMap內(nèi)部維護(hù)了值棧本身(OgnlValueStack)以及根(ComponentRoot)的引用.實(shí)際上,也可以看出來(lái)值棧的contextMap的實(shí)際數(shù)據(jù)結(jié)構(gòu)為OgnlContext.接下來(lái)我們跟蹤在PreparedOperations類內(nèi)部createActionContext方法的stack.getContext().putAll這一句(上面標(biāo)注的第二步).直接進(jìn)入dispatcher.createContextMap的內(nèi)部.
可以看出這個(gè)操作,就是在contextMap內(nèi)部加入了各個(gè)域?qū)ο?request,ServletContext,session)的引用.通過(guò)contextMap可以獲取到各個(gè)域?qū)ο蟮囊?
返回,在createActionContext方法內(nèi),繼續(xù)往下走,第三步,可以看出將值棧(OgnlValueStack)的contextMap作為ActionContext的構(gòu)造方法的參數(shù)傳了進(jìn)去.進(jìn)入ActionContext類,實(shí)際上其內(nèi)部是維護(hù)了一個(gè)叫做context的map來(lái)指向OgnlValueStack的contextMap的.而構(gòu)造方法,正是對(duì)這個(gè)叫做context的成員變量初始化賦值.
實(shí)際上,ActionContext獲取值棧.獲取contextMap.獲取Servlet相關(guān)的API都是通過(guò)這個(gè)context來(lái)實(shí)現(xiàn)的:
返回createActionContext方法,進(jìn)入第四步.也就是ActionContext.setContext()方法.這個(gè)方法將新建的ActionContext以靜態(tài)方法的參數(shù)傳入ActionContext.進(jìn)入這個(gè)方法內(nèi)部:
原來(lái)這個(gè)方法是將新創(chuàng)建的ActionContext綁定到了ThreadLocal上.ThreadLocal的set方法是將ThreadLocal對(duì)象和數(shù)據(jù)對(duì)象作為鍵值對(duì)存入線程對(duì)象內(nèi)部的一個(gè)Map類型的數(shù)據(jù)結(jié)構(gòu)里.因此,由于ActionContext被綁定在ThreadLocal對(duì)象上,所以ActionContext是線程安全的.
綜上,這就是值棧的創(chuàng)建過(guò)程.可以看出ActionContext和值棧同時(shí)創(chuàng)建,而且都是一次請(qǐng)求創(chuàng)建一次.生命周期為1次請(qǐng)求!值棧包括兩部分:contextMap和root.其中contextMap維護(hù)了值棧本身和root的引用.ActionContext內(nèi)部維護(hù)了contextMap的引用,因此一些教程上說(shuō)的,ActionContext內(nèi)部維護(hù)了值棧的引用是不正確的!正確的說(shuō)法應(yīng)該是ActionContext內(nèi)部維護(hù)了contextMap的引用,contextMap內(nèi)部維護(hù)了值棧的引用!為了便于理解,我畫出了下面的圖,僅供參考:?
?
轉(zhuǎn)載于:https://www.cnblogs.com/hlhdidi/p/6185836.html
總結(jié)
以上是生活随笔為你收集整理的struts2值栈内部数据结构详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: u3d中texture2D的Advanc
- 下一篇: chgrp 简明笔记