变量上下文是动作运行时存储和管理变量的容器,任何一个动作执行时都有一个变量上下文。变量上下文对应的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里保证一定要被执行到,否则变量管理就是混乱的,会发生严重问题。