beanshell和shell的区别
的有关信息介绍如下:
BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方旅哪法; BeanShell是一种松散类型的脚本语言(这点和JS类似) BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的慎乎Java源代码解释器, 具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。 BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。官网:http://www.BeanShell.org/BeanShell 将成为Java平台上的第三种编程语言,前两种分别为java和Groovy(也是一种脚本语言) 下载与安装: jar: http://www.beanshell.org/download.html src: http://www.beanshell.org/developer.html 或使用SVN: svn co http://ikayzo.org/svn/beanshell doc: http://www.beanshell.org/docs.html 设置环境: (1) 把bsh-xx.jar放到$JAVA_HOME/jre/lib/ext文件夹下(不推荐); (2) UNIX: export CLASSPATH=$CLASSPATH:bsh-xx.jar(推荐) (3) WINDOWS: set classpath %classpath%;bsh-xx.jar(推荐) 运行方式: (1) 界面UI方式 : java bsh.Console (2) 命令行方式 : java bsh.Interpreter (3) 运行脚本文件: java bsh.Interpreter filename [args] 简单举例(windows):设置好环境变量classpath, 打开dos或CMD窗口, 键入命令: java bsh.Console 出现BeanShell的"Bsh Workspace"拆孝码界面,表示设置成功,BeanShell开始运行; 在使用上面命令出现的控制台界面中进行下面的测试:bsh % foo="Foo"; //定义变量foo bsh % four=(2+2)*2/2; //定义变量four并初始化为(2+2)*2/2 bsh % print(foo+"="+four); //输出 Foo=4 Foo=4 //输出结果 bsh % for(i=0;i<5;i++)print(i); //循环打印0~4 0 1 2 3 4 bsh % button = new JButton("MyButton"); //实例化一个Button对象 bsh % frame = new JFrame("MyFrame"); //实例化一个Frame对象 bsh % frame.getContentPane().add(button,"Center"); //将Button对象加入Frame对象的面板中; bsh % frame.pack(); //打包 bsh % frame.setVisible(true); //设置Frame对象的可见性;回车后会弹出一个GUI界面; bsh %完整代码:foo = "Foo"; four = (2 + 2)*2/2; print( foo + " = " + four ); for (i=0; i<5; i++) print(i); button = new JButton( "My Button" ); frame = new JFrame( "My Frame" ); frame.getContentPane().add( button, "Center" ); frame.pack(); frame.setVisible(true); 在窗口中输入上面的代码, 敲回车执行,弹出一个有Button的GUI界面. 说明: 因为BeanShell是松散类型的脚本语言因此可以直接写: foo = "Foo"; four = (2 + 2)*2/2; 也就是foo与four均不需要变量类型的声明,给赋什么类型的值,就是什么类型的变量; print()是BeanShell提供一种简单的打印命令,相当于java中的System.out.println(); 脚本中所写的方法范例:int addTwoNumbers( int a, int b ) { return a + b; } sum = addTwoNumbers( 5, 7 ); // 12 也可以使用动态的变量类型(无状态)方法 add(a, b){ return a + b; } foo = add(1, 2); // 3 foo = add(1, "2"); //"12"特别注意: 只要有一个为字符串全部按照字符串处理, 系统不会根据1是数字在前把"2"转换成数字处理; foo = add("Oh", " baby"); // "Oh baby" 脚本中实现接口:实现任何接口需要JDK1.3或者更高,可以使用缺省的java匿名类的语法实现一个接口类,例如: ActionListener scriptedListener = new ActionListener() { actionPerformed( event ) { ... } }不需要实现接口的所有的方法,只需要实现你使用的方法即可, 如果使用你没有实现的方法,BeanShell将抛出一个错误,如: ml = new MouseListener() { mousePressed( event ) { print("test"); } // handle the rest invoke( name, args ) { print("Method: "+name+" invoked!"); } }脚本中定义对象:例一: 使用特殊的关键字this可以创建一个对象(根JS类似) foo() { print("foo"); x=5; bar() { print("bar"); } return this; } myfoo = foo(); // prints "foo" print( myfoo.x ); // prints "5" myfoo.bar(); // prints "bar" 例二: 在java标准语言中可以使用this返回一个类的一个实例 // MyClass.java MyClass { Object getObject() { return this; // return a reference to our object } } 在这个例子中getObject() 方法是返回MyClass类的一个实例在BeanShell中对象中的变量只是局部的变量在对象内可以使用,在对象外是不可以使用的(不同于前面for-loop,if-else中的使用); // Define the foo() method: foo() { bar = 42; print( bar ); } // Invoke the foo() method: foo(); // prints 42 print(bar); // Error, bar is undefined here 这里的print(bar);会抛出异常: // Error: EvalError: Undefined argument: bar : at Line: 1 : in file: : ( bar ) 但可以使用this返回对象,使用对象加上"."运算符引用属性(类似JS) foo() { bar = 42; return this; } fooObj = foo(); print( fooObj.bar ); // prints 42同样对象中也可以定义一些方法,例如: foo() { int a = 42; bar() { print("The bar is open!"); } //bar(); return this; } // Construct the foo object fooObj = foo(); // prints "the bar is open!" // Print a variable of the foo object print ( fooObj.a ) // 42 // Invoke a method on the foo object fooObj.bar(); // prints "the bar is open!"也可以定义bar()和foo()也带参数: foo() { bar(int a) { print("The bar is open!" + a); } return this; } foo().bar(1);也可以把bar()方法定义到对象外面 foo() { return this; } bar(int a) { print("The bar is open!" + a); } foo().bar(1); //其实就是bar(1);BeanShell一种松散的脚本语言, 有很多中声明的方法可以使用: This super global This 是引用当前对象 Super 是引用父亲对象 Global 是引用最上层对象 super.super.super...foo = 42; // Chain super. to reach the top global.foo = 42;BeanShell(Bsh)调用外部Java类的两种方式:(1) 方法一(直接调用.java源文件) sourceRelative("xxx.java"); 利用sourceRelative()方法把java的源代码引入bsh环境中,然后进行调用。 这种方法不需要编译引用的java源文件,缺点也很明显"无法利用javac来检查java代码"。(2) 方法二(通过引用.class二进制文件) import xxx; 利用传统的java import机制来获取java类,然后在bsh环境中进行调用。 需要编译.java文件; 方便调用第三方的Java API(因为通常情况下无法得到API的源码,即使得到了文件会远大于jar包的大小)。 BeanShell介绍:我们知道,现在有很多脚本语言,大家平时使用的比较多的包括Perl,Python,Ruby,JavaScript,Groovy,在这里我要介绍的是另外一个对象脚本语言BeanShell(http://www.BeanShell.org)。BeanShell的解释器是用Java写的,开源并且免费的,引用open-open上面的话来说明它的运作方式: 它将脚本化对象看作简单闭包方法(simple method closure)来支持, 就如同在Perl和JavaScript中的一样。它具有以下的一些特点: * 使用Java反射API以提供Java语句和表达式的实时解释执行; * 可以透明地访问任何Java对象和API; * 可以在命令行模式、控制台模式、小程序模式和远程线程服务器模式等四种模式下面运行; * 与在应用程序中一样,可以在小程序中(Applet)正常运行(无需编译器或者类装载器); * 非常精简的解释器, jar文件中的Intepreter.class大小为150+k"。每一种脚本语言都有它的使用场景,而正是因为其在某些场景的使用而使语言本身得到了发扬光大,比如Ruby正是因为Ruby On Rails这个Web框架的流行而得到开发者的关注,Groovy也一样;BeanShell可不能再有Web框架,Java世界的Web框架已经太多了,够让人头痛的了;BeanShell是Java语法,所以对Java开发者来说,很快就可以上手,BeanShell不能像Ruby,Perl,Ruby一样可以占据一个系统的主体,而只能在一些小的地方发挥"螺丝钉"的作用。笔者与BeanShell结缘是通过一个开源工作流引擎-OBE(这个鸟东西现在好像没什么声音了),BeanShell被用作流程跳转的Parser,举个例子,比如一个流程A节点的下一个节点是B或者C,如何决定A->B还是A->C呢,我们可以写一段Java脚本放在流程定义里面,一旦A运行完毕,流程会使用BeanShell来Parse这段Java脚本,根据脚本的返回值决定流程下一步的运行方向,脚本在这里虽然用得不多,但是却是非常的重要,我们知道,简单的表达式是远远满足不了流程跳转的判断的,有了脚本就可以满足任何不规则的业务逻辑。继以上说到的,使用BeanShell可以处理现实中不规则的业务,举个很典型的例子,我们知道,一个保险公司有很多险种,每个险种的投入和收益的算法是很复杂的,无法用规则的关系数据库模型来描述,所以很多保险系统在处理险种的算法都是硬编码,如果要在系统中新加一个险种,是非常麻烦的,重新修改代码,重新发布,这对开发\维护人员和客户都是很痛苦的,有了BeanShell,我们可以从这种痛苦中解脱出来,对每个险种使用不同的脚本,新加的险种我们新配一个脚本,这样既可以满足业务多变的要求,又可以减少工作量,节约成本。BeanShell的一个特点是动态执行Java代码,脚本文件改变不会影响当前脚本的调用,新脚本将在脚本的下一次调用生效,这不同于配置文件,配置文件改变一般都需要应用重启。 下面举个例子来说明BeanShell的使用(JDK1.5,BeanShell2.04),主类: package com.test.BeanShell; import bsh.Interpreter; public class TestShell { public static void main(String[] args) throws Exception { Interpreter interpreter = new Interpreter(); interpreter.set("inValue", new Integer(1)); interpreter.source("/D://BeanShell_test/test.bsh"); System.out.println(((Integer) interpreter.get("outValue")).intValue()); } }脚本文件(D:/BeanShell_test/test.bsh)中的内容为:: System.out.println("hello,in value is "+inValue); outValue = inValue+1;结果: hello,in value is 1 2 再来一个简单例子:(1) 下载BeanShell的jar,加到 classpath 里(2) 写一个脚本文件 myscript.txt ,内容如下: a = 2; b = 3; c = a + b; print(c);(3) 运行该脚本 d:\BeanShell>java bsh.Interpreter myscript.txt 如果没有将BeanShell的JAR加到classpath路径里,运行下面的命令: java -classpath %CLASSPATH%;bsh-2.0b4.jar bsh.Interpreter myscript.txt OK,输出结果5写一个bat文件 bsh.bat放到系统目录下,如:winnt 文件内容如下: java bsh.Interpreter %1就可以使用如下方法运行脚本文件了 c:\BeanShell>bsh myscript.txtosworkflow用的就是他了和Eclipse的集成: http://eclipse-shell.sourceforge.net/index.htmleclipse update url: http://eclipse-shell.sourceforge.net/update/有用的BeanShell命令:在刚才那个例子中我们用了一个内建在BeanShell中的一个方便的命令print(),来显示变量的值。print()跟Java的System.out.println()非常的相像,除非它能保证输出总是命令行。print()也可以显示一些对象的类型(如数组),但比Java的更详细。另一个相关的命令是show(),用来开启与关闭显示你输入的每一行的结果。