OgnlContext源码分析

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以及他的一些属性共同维护的。

没有更多推荐了,返回首页