动作相当于函数和方法,所以它要能够处理各种变量,变量上下文就是管理变量的容器,在调用动作时作为参数传入。
变量上下文对应的Java类是org.xmeta.ActionContext。
可以把变量上下文做为一个Map。
import org.xmeta.ActionContext; ActionContext actionContext = new ActionContext(); //设置变量 actionContext.put('varName", varObj); //获取变量 Object varObj = actionContext.get("varName");
变量上下文不仅相当于Map,它还是一个栈(Stack)。
import org.xmeta.ActionContext; import org.xmeta.Bindings; ActionContext actionContext = new ActionContext(); //设置变量a=10 actionContext.put("a", 10); assert ationContext.get("a") == 10; //压入一个变量栈 Bindings bindings = actionContext.push(); bindings.put('a", 20); //此时变量a=20 assert actionContext.get("a") == 20; //弹出变量栈 actionContext.pop(); //此时变量a恢复为10 assert actionContext.get("a") == 10;
由于变量变量上下文也是一个栈,而栈的push和pop是成对的,并且是在一个线程里完成的,这样就存在线程安全的问题。变量上下文(ActionContext)的解决方法是每一个栈都是线程绑定的,即使用ThreadLocal来保存栈,这样每个线程的栈都是独立的。
虽然变量上下文中的栈是线程独立的,但栈的最底层的那个变量范围是公共的,这个变量范围是在变量上下文创建时就是push的,它默认加入到每一个线程的栈中,因此也使用中也不会被其他线程弹出(pop),所以相当于全局变量。
可以通过actionContext.g()或actionContext.getScope(0)来获取,在Groovy等脚本中变量_g通常也是全局变量范围。
有全局变量的概念,那么也有局部变量的概念,局部变量由动作模型自行控制。
actionContext.peek().setVarScopeFlag(); //设置局部变量范围的标识
上面的语句就把当前的栈层设置为了局部变量,局部变量可以通过下面的方式获得。
//最近的一个局部变量 Bindings l = actionContext.l(); //第二近的局部变量,序列从0开始l()等于l(0) Bindings l = actionContext.l(1);
局部变量的作用。
//以上代码的示意代码如下 { String name = "hello world"; { String name = "hello world1"; } }
在以上示意代码中,actionContext.l().get("name")返回的是hello world1,而actionContext.l(1).get("name")返回的是hello world。
Copyright © 2007-2019 XWorker.org 版权所有 沪ICP备08000575号