原文出處:http://blog.chenlb.com/2010/06/java-invoke-groovy.html
java 結合 xml 是多年經典組合。但我覺得變化多的、配置復雜的、靈活的系統,xml 簡直就是惡夢。因為配置復雜的系統需要點編程能力。而 xml 沒有編程能力,那么動態語言在這需求上發揮很好的作用。比如規則引擎。現在先簡單示例下 java 中使用 groovy。
java 中執行 groovy 寫的邏輯。
- println 'start!'
- def foo(abc) {
- if(m && m.get('name')) {
- println "hello "+m.get('name')
- }
- println "param = "+abc
- return abc*10
- }
- def add(a, b) {
- a + b
- }
- i = 123 + 5
- println i
- m = ['name':'http://blog.chenlb.com']
- if(m && m.get('name')) {
- println "id="+m.get('name')
- }
- println "end!"
- return 100+2
java 的調用示例:
- package com.chenlb.groovy;
- import groovy.lang.GroovyClassLoader;
- import groovy.lang.GroovyObject;
- import groovy.lang.GroovyShell;
- import java.io.File;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * @author http://blog.chenlb.com 2010-6-30 下午05:22:33
- */
- public class GroovyT {
- public static void main(String[] args) {
- ClassLoader parent = GroovyT.class.getClassLoader();
- GroovyClassLoader loader = new GroovyClassLoader(parent);
- GroovyObject groovyObject = null;
- try {
- File file = new File("src/groovy/baz.groovy");
- Map<String, String> m = new HashMap<String, String>();
- m.put("name", "chenlb");
- Class<?> groovyClass = loader.parseClass(file);
- groovyObject = (GroovyObject) groovyClass.newInstance();
- System.out.println("-> "+groovyObject.getClass());
- groovyObject.setProperty("m", m);
- Object result = groovyObject.invokeMethod("foo", new Integer(2));
- System.out.println(result+" -> "+result.getClass());
- result = groovyObject.invokeMethod("add", new Object[]{2, 3});
- System.out.println(result+" -> "+result.getClass());
- result = groovyObject.invokeMethod("main", new String[]{});
- System.out.println(result);
- //run groovy
- System.out.println("=========================");
- GroovyShell gs = new GroovyShell(parent);
- gs.setVariable("m", m);
- Object r = gs.evaluate(file);
- System.out.println(r); //102
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
看到這樣的結果:
-> class baz
hello chenlb
param = 2
20 -> class java.lang.Integer
5 -> class java.lang.Integer
start!
128
id=http://blog.chenlb.com
end!
null
=========================
start!
128
id=http://blog.chenlb.com
end!
102
調用方法用 GroovyObject 使用 groovy 中的方法。GroovyObject 又用 GroovyClassLoader 加載。如果方法中要使用到上下文,可以用groovyObject.setProperty設置。
還默認有個 main 個方法,些方法是執行 groovy 文件的,但沒有返回值,因為它使用 java 的 main(void) 方法,執行 main 方法 groovyObject.setProperty 無效(這也可以理解 main 是靜態的)。
也可以用 GroovyShell 來執行 groovy 文件。這種方式可以得到返回值,可以用 setVariable 設置上下文環境(驗證有效,把 baz.groovy 的 16 行注釋掉,同時把 GroovyT.java 的 27-40 行注釋掉)。