OgnlContext源码分析

来源:互联网 发布:淘宝发货时间怎么看 编辑:程序博客网 时间:2024/05/20 07:50

1,首先明确OgnlContext是大概一个什么样的数据结构:

public class OgnlContext extends Object implements Map


能够看到他实现了Map接口,那么我们就用map的眼光去看待他。


2,分析put方法

刚开始就可以看到:

 if (RESERVED_KEYS.containsKey(key)) 

2.1.RESERVED_KEYS是什么呢?
追踪一下:
private static Map RESERVED_KEYS = new HashMap(11);

那这个HashMap是用来存放什么的?
下面是重点:

static    {RESERVED_KEYS.put(CONTEXT_CONTEXT_KEY, null);        RESERVED_KEYS.put(ROOT_CONTEXT_KEY, null);RESERVED_KEYS.put(THIS_CONTEXT_KEY, null);       RESERVED_KEYS.put(TRACE_EVALUATIONS_CONTEXT_KEY, null);RESERVED_KEYS.put(LAST_EVALUATION_CONTEXT_KEY, null);RESERVED_KEYS.put(KEEP_LAST_EVALUATION_CONTEXT_KEY, null);RESERVED_KEYS.put(CLASS_RESOLVER_CONTEXT_KEY, null);RESERVED_KEYS.put(TYPE_CONVERTER_CONTEXT_KEY, null);RESERVED_KEYS.put(MEMBER_ACCESS_CONTEXT_KEY, null);}public static final String CONTEXT_CONTEXT_KEY = "context";   public static final String ROOT_CONTEXT_KEY = "root";
其他的key都是差不多意思的String

总结一下:
RESERVED_KEYS就是一个HashMap,用于存放一些保留的key,正如这个属性的名字一样。
这些保留的key就是以上这些String


继续看put方法:

if (RESERVED_KEYS.containsKey(key)) {...} else {result = values.put(key, value);}

先把简单的搞定:如果要放入的键值对的key不在保留字范围内,那就把他保存在values里面。

2.2.1values是什么呢?

private Map values = new HashMap(23);

看来也是OnglContext中的一个HashMap属性。

2.2.2values什么时候用的?

/*================= Map interface =================*/    public int size()    {        return values.size();    }    public boolean isEmpty()    {        return values.isEmpty();    }    public boolean containsKey(Object key)    {        return values.containsKey(key);    }    public boolean containsValue(Object value)    {        return values.containsValue(value);    }

看来values才是OgnlContext主要用来存储数据的地方。


2.3.再看一下当key为保留字的情况下是怎么存储的.

if (RESERVED_KEYS.containsKey(key)) {            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {                result = getCurrentObject();                setCurrentObject(value);            } else {                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {                    result = getRoot();                    setRoot(value);                } else {                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {                        throw new IllegalArgumentException("can't change " + OgnlContext.CONTEXT_CONTEXT_KEY + " in context");                    } else {                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {                            result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;                            setTraceEvaluations(OgnlOps.booleanValue(value));                        } else {                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {                                result = getLastEvaluation();                                lastEvaluation = (Evaluation)value;                            } else {                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {                                    result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;                                    setKeepLastEvaluation(OgnlOps.booleanValue(value));                                } else {                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {                                        result = getClassResolver();                                        setClassResolver((ClassResolver)value);                                    } else {                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {                                            result = getTypeConverter();                                            setTypeConverter((TypeConverter)value);                                        } else {                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {                                                result = getMemberAccess();                                                setMemberAccess((MemberAccess)value);                                            } else {                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");                                            }                                        }                                    }                                }                            }                        }                    }                }            }        } 

代码有点长,但是套路是一样的,就拿前面两种情况来说:
1.判断key是否为THIS_CONTEXT_KEY,即"this",如果是,则执行setCurrentObject(value);
关于这个方法:

 public void setCurrentObject(Object value)    {        currentObject = value;    }
原来是在OgnlContext中有一个属性叫做currentObject,意思是当前的对象,存的时候他的key为保留的"this"。
2.判断key是否为ROOT_CONTEXT_KEY,即"root",如果是,则执行setRoot(value);

public void setRoot(Object value)    {        root = value;    }

同样的意思

总结:原来在OgnlContext有很多固定的属性(就是上面说的“保留字”),除了这些固定的属性,还有一个叫做values的HashMap,
values这个HashMap以及OgnlContext中属性一起实现了Map结构。



3.分析get方法:
 public Object get(Object key)    {        Object      result;        if (RESERVED_KEYS.containsKey(key)) {            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {                result = getCurrentObject();            } else {                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {                    result = getRoot();                } else {                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {                        result = this;                    } else {                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {                            result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;                        } else {                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {                                result = getLastEvaluation();                            } else {                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {                                    result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;                                } else {                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {                                        result = getClassResolver();                                    } else {                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {                                            result = getTypeConverter();                                        } else {                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {                                                result = getMemberAccess();                                            } else {                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");                                            }                                        }                                    }                                }                            }                        }                    }                }            }        } else {            result = values.get(key);        }        return result;    }

有了put的基础,这个看一眼就知道是什么意思了,怎么put进去的就怎么取出来。


4.其他的方法:

4.1.clear

 public void clear()    {        values.clear();        setRoot(null);        setCurrentObject(null);        setRootEvaluation(null);        setCurrentEvaluation(null);        setLastEvaluation(null);        setCurrentNode(null);        setClassResolver(DEFAULT_CLASS_RESOLVER);        setTypeConverter(DEFAULT_TYPE_CONVERTER);        setMemberAccess(DEFAULT_MEMBER_ACCESS);    }

看了这个方法,也证明了之前得出的结论,这个map是由values以及他的一些属性共同维护的。

0 0
原创粉丝点击