OgnlContext、OgnlValueStack、CompoundRoot的数据结构

在上一篇从struts2的action中看ActionContext的存储结构中已经看到ActionContext.getActionContext.getContextMap()得到的map的大体结构类型。

这篇将从源代码层面进行分析。


一、回顾

在上一篇中看到ActionContext中存放的是OgnlContext这个类,这个类的源代码,在OgnlContext源码分析中已经将的比较清楚了。那么值栈ValueStack到底是什么鬼。

二、ValueStack

我们就从ActionContext类中的getValueStack()方法入手:

    public ValueStack getValueStack() {
        return (ValueStack) get(VALUE_STACK);
    }
    public Object get(String key) {
        return context.get(key);
    }
看来要得到这个值栈,还是要从context这个所谓的map中去取。

这个context的实际类型是OgnlContext,还记得OgnlContext是由一系列保留的Object以及一个HashMap共同维护的:先找保留的key,找不到再去HashMap中去找。

这里的key为VALUE_STACK,是要从HashMap中取的(还记得这个HashMap的属性名为_values)

也就是说,ValueStack是藏在OgnlContext中_values属性的hashMap的key为VALUE_STACK对应的值中。


在action中打印一下ValueStack真实的类:

System.out.println(ActionContext.getContext().getValueStack().getClass());

//结果
//class com.opensymphony.xwork2.ognl.OgnlValueStack
那么我们就打开OgnlValueStack来看里面的源代码。


三、OgnlValueStack

1.两个重要的属性

    CompoundRoot root;
    transient Map<String, Object> context;

2.先来说说这个叫做root的属性:

CompoundRoot比较陌生,打开类看一下:

/*
 * Copyright 2002-2006,2009 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opensymphony.xwork2.util;

import java.util.ArrayList;
import java.util.List;


/
 * A Stack that is implemented using a List.
 * 
 * @author plightbo
 * @version $Revision: 894090 $
 */
public class CompoundRoot extends ArrayList {

    public CompoundRoot() {
    }

    public CompoundRoot(List list) {
        super(list);
    }


    public CompoundRoot cutStack(int index) {
        return new CompoundRoot(subList(index, size()));
    }

    public Object peek() {
        return get(0);
    }

    public Object pop() {
        return remove(0);
    }

    public void push(Object o) {
        add(0, o);
    }
}

这样看来,不要太简单,就把他当做是一个Stack来看把。

3.再来看看这个context属性:

在OgnlValueStack的构造方法都调用的

    protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,
                           boolean allowStaticMethodAccess) {
        this.root = compoundRoot;
        this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess);
        this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess);
        context.put(VALUE_STACK, this);
        Ognl.setClassResolver(context, accessor);
        ((OgnlContext) context).setTraceEvaluations(false);
        ((OgnlContext) context).setKeepLastEvaluation(false);
    }
这里又多出一个Ognl工具类,先不用管具体的代码,只要知道Ognl.createDefaultContext他是产生了一个OgnlContext对象,然后返回。

应该还记得,OgnlContext这个类实现了Map接口,Map context=ognlContext是完全没问题。

到这里也要记住,root他放的是一个stack,context放的是一个OgnlContext

四、OgnlContext

再回来看下Ongl这个工具类是怎么初始化一个OgnlContext对象的。

    public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess )
    {
        return addDefaultContext( root, classResolver, converter, memberAccess, new OgnlContext() );
    }

public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context )
    {
        OgnlContext     result;

        if (!(context instanceof OgnlContext)) {
            result = new OgnlContext();
            result.setValues(context);
        } else {
            result = (OgnlContext)context;
        }
        if (classResolver != null) {
            result.setClassResolver(classResolver);
        }
        if (converter != null) {
            result.setTypeConverter(converter);
        }
        if (memberAccess != null) {
            result.setMemberAccess(memberAccess);
        }
        result.setRoot(root);
        return result;
    }

参数太多不管,只要看到root传过来就行了。

然后在return之前调用了setRoot方法,什么意思呢?

在OgnlContext中的_root属性上放的是一个Stack,就是叫做CompoundRoot的那个东西。


五、总结

可以看到,OgnlContext、OgnlValueStack之间的互相引用有些复杂:

OgnlContext=保留字+HashMap

HashMap=key:value...+value_stack:ognlValueStack

保留字=其他保留字+CompoundRoot


OgnlValueStack=CompoundRoot+OgnlContext

上丑图:

OgnlContext、OgnlValueStack、CompoundRoot的数据结构

更多相关文章
  • 来源:中国台湾网中国台湾网8月5日讯 台湾宏达电子公司(亦称HTC)一名男员工,日前趁女性友人到桃园公司会客时,两人在会议室嘿咻,亲热过程遭人用手机偷拍.视频长达一分钟,与日前大陆出现的"优衣库试衣间不雅视频"极为相似.宏达电子方面目前已证实此事,并表示已完成内部调查,解雇该员工 ...
  • Android的对话框有两种:PopupWindow和AlertDialog.它们的不同点在于: AlertDialog的位置固定,而PopupWindow的位置可以随意 AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的 PopupWindow的位置按照有无偏移分,可以分为 ...
  • 一.生成APK Build-->Generate Signed APK... 以上是创建密钥库及密钥,创建后会自动选择刚创建的密钥库和密钥.若已经创建过输入password即可. 若第一次或需要新建点击Create new... Key store path:密钥库文件的地址 Password ...
  • 构思: 在首页(MainPage)上定义一个代表应用版本号的字符串,网站上写一个接口(让这个字符串与你的最新应用版本号进行比较,返回应用的ContentIdentifier与操作状态什么的). 一.wp客户端 using System; using System.Collections.Generi ...
  • 几年前,我们这样写前端代码: <div id="el" style="......" onclick="......">测试</div> 慢慢的,我们发现这样做的很多弊端,单就样式一块,改一个样式会涉及到多处调整,所 ...
  • 如何安装WIN7系统过程图解   下面请看WIN7安装的全过程:   首先在开启电脑时,要进入主板BIOS设置成光盘启动:     重新启动电脑,出现提示Enter Boot from CD rom,按Enter就进入安装界面:  www.2cto.com         根据中文提示进行操作就是了 ...
一周排行
  • linux系统管理之无人值守网络安装linux操作系统 一.一,网络安装的相关准备 需要准备的服务 Tftp(TFTP是用来下载远程文件的最简单网络协议,它其于UDP协议而实现.嵌入式linux的tftp开发环境包括 ...
  • 易网科技讯 5月4日消息,畅游有限公司(纳斯达克股票交易代码:CYOU)公布了截止到2009年3月31日的第一季度未经审计的财报.财报显示,2009年第一季度,畅游超出搜狐指导性预期收入160万美元:总收入创记录达到 ...
  • sc create SVN binpath= "C:/Subversion/bin/svnserve.exe --service -r f:/svn" displayname= "Sub ...
  • 这一篇就简单说下一个hello world插件工程创建过程. 1.创建一个Plug-in Project     2.填写project name     3.第二个确认框勾上,然后直接下一步     4.选择Hel ...
  • 原题链接: http://oj.leetcode.com/problems/permutation-sequence/ 这道题目算法上没有什么特别的,更像是一道找规律的数学题目.我们知道,n个数的permutatio ...
  • 本周7月29日,微软全新操作系统Windows 10将在全球190个国家和地区同步上线发布.但是,对习惯了Win7和Win8的用户来说,Win10的操作问题成了头等难题.那么win10如何更改分辨率?下面小编就为大家 ...
  • 本文作者:约翰·钱伯斯(John Chambers)约翰·钱伯斯(John Chambers)是思科公司(Cisco)总裁兼首席执行官,以下是他发表在2014世界经济论坛(WEF)网站上的一篇博文:“万联网”是指将人 ...
  • 下一代防火墙功能强大,你是不是对它们感到有点迷惑. 所谓的下一代防火墙(NGFW)是什么? 下一代防火墙缩写为NGFW,目前被多数厂商描述为拥有多功能安全防御和基于身份的应用控制在内的新型防火墙.这一描述得到了市场研 ...
  • 段晓燕 王冠 北京报道 保持对一些企业和企业家的跟踪观察,是很有意义的.譬如,我们最近采访的两位企业家:郭台铭和马云. 二人是至交好友,从思想到生意,相交甚深:二人均白手起家,打拼天下,一个是台湾商界资深翘楚,一个是 ...
  • 时不时看到个别网友说自己网上赚钱的帐户被封,下面我来谈谈google adsense帐户安全问题. 时不时看到个别网友说自己网上赚钱的帐户被封,下面我来谈谈google adsense帐户安全问题. 1.google ...