Beanshell (bsh) 是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性。
BeanShell执行 标准Java语句和表达式,另外包括一些脚本命令和语法。它将脚本化对象看作简单闭包方法(simple method closure)来支持,就如同在Perl和JavaScript中的一样。 它具有以下的一些特点:使用Java反射API以提供Java语句和表达式 的实时解释执行;可以透明地访问任何Java对象和API;可以在命令行模式、控制台模式、小程序模式和远程线程服务器模式等四种模式下面运行;与在应用 程序中一样,可以在小程序中(Applet)正常运行(无需编译器或者类装载器)
@百度百科
简单的来说,Beanshell提供了一种将Java代码作为脚本动态执行能力。关于Beanshell的简介网上可以找到很多文章,本文不再复述,本文主要说明在如何在脚本中引用自定义的变量和方法和定义运行时变量
如下我们定义了一个类,实现了runScript方法执行指定的脚本,并实现了一个叫isEmpty的方法判断一个对象是否为空,
我们希望能执行runScript方法执行Beanshell脚本时,在Beanshell脚本中能调用isEmpty方法.
public class TestClass{
/** bsh解释器实例 */
private Interpreter interpreter = new Interpreter();
/**
* BeanShell运行环境调用的方法:判断一个对象是否为null或空,参见{@link BeanPropertyUtils#isEmpty(Object)}
* @param value
*/
public boolean isEmpty(Object value) {
if(null == value){
return true;
}else if(value instanceof String){
return ((String)value).isEmpty();
}else if (value instanceof Collection) {
return ((Collection)value).isEmpty();
}else if (value instanceof Iterator) {
return !((Iterator)value).hasNext();
}else if (value instanceof Iterable) {
return !((Iterable)value).iterator().hasNext();
}else if (value instanceof Map) {
return ((Map)value).isEmpty();
}else if (value.getClass().isArray()) {
return Array.getLength(value)==0;
}
return false;
}
/**
* 执行指定的脚本
*/
public void runScript(String script){
interpreter.eval(script);
}
}
Interpreter
的 getNameSpace
方法返回的NameSpace
对象的importObject
方法可以将指定对象的public方法和变量引入Beanshell脚本的运行时的名字空间,这样Beanshell脚本就可以引用导入的方法了,所以我们可以如下增加构造方法
TestClass(){
// 将当前对象添加到namespace,这样脚本中才可以访问对象中的方法,isEmpty
interpreter.getNameSpace().importObject(this);
}
有了上面的引入方法,就可以如下执行脚本
TestClass bsh = new TestClass();
Object value = "hello,world";
bsh.runScript("if(!isEmpty(\"+ value +\"))print(\"no empty\");")
Interpreter
的set
方法用于为Beanshell运行空间定义指定变量名的变量,示例如下:
/**
* 定义脚本执行变量,在{@link #with(Object)}方法之后调用有效
* @param varname 变量名,为空或{@code null}忽略
* @param value 变量的值
* @return 当前对象
*/
public TestClass defineVariable(String varname,Object value) {
if(!isNullOrEmpty(varname)){
try {
interpreter.set(varname, value);
SimpleLog.log(debuglog,"{} = {}",varname,value);
} catch (EvalError e) {
throw new RuntimeException(e);
}
}
return this;
}
有了上面的变量定义方法,就可以如下执行脚本
TestClass bsh = new TestClass();
bsh.defineVariable("value",new ArrayList());
bsh.runScript("if(!isEmpty(value))print(\"no empty\");")