原文出处: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 行注释掉)。