变量上下文是动作运行时存储和管理变量的容器,任何一个动作执行时都有一个变量上下文。变量上下文对应的Java类是org.xmeta.ActionContext。
变量是一个Map和Stack的结合体,通过Map和Stack实现存储和管理变量的目的,下面是常见的用法。
import org.xmeta.ActionContext; import org.xmeta.Bindings; //创建变量上下文 ActionContext actionContext = new ActionContext(); //推荐通过栈存储变量 Bindings bindings = actionContext.peek(); bindings.put(key, value); //存储变量,key是String,value是Object //不推荐通过acitonContext直接存储变量,因此存在风险 actionContext.put(key , value); //获取变量,一般通过actionContext获取,而不是通过栈 Object value = actionContext.get(key);b
变量范围是指变量的生效范围,动作执行时只有一个变量上下文,变量的范围就是在变量上下文内部体现的。
import org.xmeta.ActionContext; import org.xmeta.Bindings; //创建变量上下文 ActionContext actionContext = new ActionContext(); //存放变量 actionContext.put("v", 1); //打印变量,输出的是1 println(actionContext.get("v")); //压入栈 Bindings bindings = actionContext.push(); bindings.put("v", 2); //打印变量,输出的是2 println(actionContext.get("v')); //压入栈 Bindings bindings = actionContext.push(); bindings.put("v", 3); //打印变量,输出的是3 println(actionContext.get("v')); //弹出栈 actionContext.pop(); //打印变量,输出的是2 println(actionContext.get("v')); //弹出栈 actionContext.pop(); //打印变量,输出的是1 println(actionContext.get("v'));
通过上面的示意代码克制变量范围的控制是通过栈操作的,而实现是通过actionContext.get("xxx")方法实现的。
变量上下文创建后默认有一个变量栈,这个栈中的变量是全局的,而局部变量栈是由动作自行控制的,即动作在压入一个栈时如果指定该站为局部的,那么这个栈就是一个局部变量范围的栈。通常全局变量栈只有一个,而局部变量栈有0到多个。
动作和行为也可以看作是函数,有时需要传入参数,方法见下面的示意代码。
//通过Map传入参数 Map<String, Object> params = new HashMap<String, object>(); params.put(param1, value1); params.put(param2, value2); //传入动作 action.run(new ActionContext(), params); //传入行为 thing.doAction("xx", new ActionContext(), params); //以上也可以通过栈的方式实现 Bindings params = actionContext.push(); try{ params.put(param1, value1); params.put(param2, value2); }finally{ //push和pop要严格成对出现 actionContext.pop(); }
变量上下文是线程安全的,因为除了全局变量栈是每个线程共有的,其它所有栈层都是线程独立的。
需要注意的是在变量上下文的push和pop栈操作是要绝对成对出现的,通常pop要放到try/finally里保证一定要被执行到,否则变量管理就是混乱的,会发生严重问题。