值栈是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内部维护了值栈的引用!为了便于理解,我画出了下面的图,仅供参考:

struts2值栈内部数据结构详解的更多相关文章

  1. [转]Redis内部数据结构详解-sds

    本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...

  2. 探索Redis设计与实现6:Redis内部数据结构详解——skiplist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  3. 探索Redis设计与实现7:Redis内部数据结构详解——intset

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  4. 探索Redis设计与实现5:Redis内部数据结构详解——quicklist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  5. 探索Redis设计与实现4:Redis内部数据结构详解——ziplist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  6. 探索Redis设计与实现3:Redis内部数据结构详解——sds

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  7. 探索Redis设计与实现2:Redis内部数据结构详解——dict

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  8. 【转】Redis内部数据结构详解——ziplist

    本文是<Redis内部数据结构详解>系列的第四篇.在本文中,我们首先介绍一个新的Redis内部数据结构--ziplist,然后在文章后半部分我们会讨论一下在robj, dict和zipli ...

  9. 【转】Redis内部数据结构详解 -- skiplist

    本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...

随机推荐

  1. Javascript模块化编程(三):require.js的用法(转)

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...

  2. cmd光标移动

    ESC:清除当前命令行.F1: 单字符输出上次输入的命令 相当于方向键上的 → 的作用.F2: 可复制字符数量 , 输入上次命令中含有的字符,系统自动删除此字符后的内容.F3: 重新输入前一次输入的命 ...

  3. 目标检测方法——SSD

    SSD论文阅读(Wei Liu--[ECCV2016]SSD Single Shot MultiBox Detector) 目录 作者及相关链接 文章的选择原因 方法概括 方法细节 相关背景补充 实验 ...

  4. try,catch,finally含return时的执行顺序及丢失的伪例

    最近面试遇到一个之前也看到过但没去看一下的问题.就是有return情况下的try,catch,finally的执行顺序. 今天写了下. 先看顺序问题.总结如下: 一:finally中没有写return ...

  5. Server.MapPath和Request.PhysicalApplicationPath的异同

    很多人对它们都不陌生,在众多的WEB程序中,使用Server.MapPath和Request.PhysicalApplicationPath来操作目录/文件的几率参半,我曾经也经常混用,然而时间久了. ...

  6. html与css面试结合工作的总结难点

    面试的时候一般会常常问起的,同时也是工作的时候会常常问道的几个问题,一下之列表内容,详细的后会附有文章,希望能帮到大家,同时有不足希望大家多多补充交流. 1.主要是的是浮动的问题(常见的问题有,三列布 ...

  7. Win7下清除SQL SERVER 2008的SSMS保存的登录信息

    C:\Users\{用户名}\AppData\Roaming\Microsoft\Microsoft SQL Server\100\Tools\Shell\

  8. python核心编程学习记录之执行环境

  9. linux中oops信息的调试及栈回溯【转】

    本文转载自:http://blog.csdn.net/kangear/article/details/8217329 ========================================= ...

  10. HTML5的Video标签的属性,方法和事件汇总

    <video>标签的属性 src :视频的属性 poster:视频封面,没有播放时显示的图片 preload:预加载 autoplay:自动播放 loop:循环播放 controls:浏览 ...