JAVA嵌入運行Groovy腳本

一.GroovyShell代碼樣例

 1) 簡單的表達式執行,方法調用

/**
 * 簡答腳本執行
 * @throws Exception
 */
public static void evalScriptText() throws Exception{
	//groovy.lang.Binding
	Binding binding = new Binding();
	GroovyShell shell = new GroovyShell(binding);
	
	binding.setVariable("name", "zhangsan");
	shell.evaluate("println 'Hello World! I am ' + name;");
	//在script中,聲明變量,不能使用def,不然scrope不一致.
	shell.evaluate("date = new Date();");
	Date date = (Date)binding.getVariable("date");
	System.out.println("Date:" + date.getTime());
	//以返回值的方式,獲取script內部變量值,或者執行結果
	//一個shell實例中,全部變量值,將會在此"session"中傳遞下去."date"能夠在此後的script中獲取
	Long time = (Long)shell.evaluate("def time = date.getTime(); return time;");
	System.out.println("Time:" + time);
	binding.setVariable("list", new String[]{"A","B","C"});
	//invoke method
	String joinString = (String)shell.evaluate("def call(){return list.join(' - ')};call();");
	System.out.println("Array join:" + joinString);
	shell = null;
	binding = null;
}

 2)  僞main方法執行.

/**
 * 當groovy腳本,爲完整類結構時,能夠經過執行main方法並傳遞參數的方式,啓動腳本.
 */
public static void evalScriptAsMainMethod(){
	String[] args = new String[]{"Zhangsan","10"};//main(String[] args)
	Binding binding = new Binding(args);
	GroovyShell shell = new GroovyShell(binding);
	shell.evaluate("static void main(String[] args){ if(args.length != 2) return;println('Hello,I am ' + args[0] + ',age ' + args[1])}");
	shell = null;
	binding = null;
}

3)  經過Shell運行具備類結構的Groovy腳本

/**
 * 運行完整腳本
 * @throws Exception
 */
public static void evalScriptTextFull() throws Exception{
	StringBuffer buffer = new StringBuffer();
	//define API
	buffer.append("class User{")
			.append("String name;Integer age;")
			//.append("User(String name,Integer age){this.name = name;this.age = age};")
			.append("String sayHello(){return 'Hello,I am ' + name + ',age ' + age;}}\n");
	//Usage
	buffer.append("def user = new User(name:'zhangsan',age:1);")
			.append("user.sayHello();");
	//groovy.lang.Binding
	Binding binding = new Binding();
	GroovyShell shell = new GroovyShell(binding);
	String message = (String)shell.evaluate(buffer.toString());
	System.out.println(message);
	//重寫main方法,默認執行
	String mainMethod = "static void main(String[] args){def user = new User(name:'lisi',age:12);print(user.sayHello());}";
	shell.evaluate(mainMethod);
	shell = null;
}

4)  方法執行和分部調用

/**
 * 以面向"過程"的方式運行腳本
 * @throws Exception
 */
public static void evalScript() throws Exception{
 Binding binding = new Binding();
 GroovyShell shell = new GroovyShell(binding);
 //直接方法調用
 //shell.parse(new File(//))
 Script script = shell.parse("def join(String[] list) {return list.join('--');}");
 String joinString = (String)script.invokeMethod("join", new String[]{"A1","B2","C3"});
 System.out.println(joinString);
 ////腳本能夠爲任何格式,能夠爲main方法,也能夠爲普通方法
 //1) def call(){...};call();
 //2) call(){...};
 script = shell.parse("static void main(String[] args){i = i * 2;}");
 script.setProperty("i", new Integer(10));
 script.run();//運行,
 System.out.println(script.getProperty("i"));
 //the same as
 System.out.println(script.getBinding().getVariable("i"));
 script = null;
 shell = null;
}

二. GroovyClassLoader代碼示例

1) 解析groovy文件

/**
 * from source file of *.groovy
 */
public static void parse() throws Exception{
	GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
	File sourceFile = new File("D:\\TestGroovy.groovy");
	Class testGroovyClass = classLoader.parseClass(new GroovyCodeSource(sourceFile));
	GroovyObject instance = (GroovyObject)testGroovyClass.newInstance();//proxy
	Long time = (Long)instance.invokeMethod("getTime", new Date());
	System.out.println(time);
	Date date = (Date)instance.invokeMethod("getDate", time);
	System.out.println(date.getTime());
	//here
	instance = null;
	testGroovyClass = null;
}

2) 如何加載已經編譯的groovy文件(.class)

public static void load() throws Exception {
	GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
	BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\TestGroovy.class"));
	ByteArrayOutputStream bos = new ByteArrayOutputStream();
	for(;;){
		int i = bis.read();
		if( i == -1){
			break;
		}
		bos.write(i);
	}
	Class testGroovyClass = classLoader.defineClass(null, bos.toByteArray());
	//instance of proxy-class
	//if interface API is in the classpath,you can do such as:
	//MyObject instance = (MyObject)testGroovyClass.newInstance()
	GroovyObject instance = (GroovyObject)testGroovyClass.newInstance();
	Long time = (Long)instance.invokeMethod("getTime", new Date());
	System.out.println(time);
	Date date = (Date)instance.invokeMethod("getDate", time);
	System.out.println(date.getTime());
	
	//here
bis.close();
	bos.close();
	instance = null;
	testGroovyClass = null;
}

三. ScriptEngine

1) pom.xml依賴

<dependency>
	<groupId>org.codehaus.groovy</groupId>
	<artifactId>groovy</artifactId>
	<version>2.1.6</version>
</dependency>
<dependency>
	<groupId>org.codehaus.groovy</groupId>
	<artifactId>groovy-jsr223</artifactId>
	<version>2.1.6</version>
</dependency>

2) 代碼樣例

public static void evalScript() throws Exception{
	ScriptEngineManager factory = new ScriptEngineManager();
	//每次生成一個engine實例
	ScriptEngine engine = factory.getEngineByName("groovy");
	System.out.println(engine.toString());
	assert engine != null;
	//javax.script.Bindings
	Bindings binding = engine.createBindings();
	binding.put("date", new Date());
	//若是script文原本自文件,請首先獲取文件內容
	engine.eval("def getTime(){return date.getTime();}",binding);
	engine.eval("def sayHello(name,age){return 'Hello,I am ' + name + ',age' + age;}");
	Long time = (Long)((Invocable)engine).invokeFunction("getTime", null);
	System.out.println(time);
	String message = (String)((Invocable)engine).invokeFunction("sayHello", "zhangsan",new Integer(12));
	System.out.println(message);
}

須要提醒的是,在groovy中,${expression} 將會被認爲一個變量,若是須要輸出"$"符號,須要轉義爲"\$".   java

關於ScriptEngine更多介紹,請參考. http://shift-alt-ctrl.iteye.com/blog/1896690 shell

相關文章
相關標籤/搜索