java与Groovy的整合

java

Groovy是构建在JVM上的一个轻量级却强大的动态语言.因为Groovy就是用Java写的,Groovy可以做到与Java的无缝兼容,可以使用Java强大的类库 而且Groovy最终也会被编译成class文件.

Groovy在1.0版的时候还存在性能问题,因为Groovy的很多实现都是用反射来做的,但是现在Groovy 1.1快推出了,据说快了10x...现在JetBrains也加入了Groovy Team旨在改善Groovy的性能,在Groovy2.0的时候还可能加上JIT,那性能就不成问题了,看来Groovy已经不是小打小闹了.而且随之而来的Grail.等基于Groovy的框架的推出,Groovy前景一片大好啊.

这篇文章不是为了讲Groovy的一些语法,而是说他怎么和Java做整合.

  • 静态使用Groory

1.运行Groovy类.

Groovy最终是会被编译成Java 的Class类的,所以Java是可以直接使用Groovy的类的.

如下,先是一个Groovy类:

package com.test;

class TestGroovyHelloWorld {

def doit(){

println "hello world!"

}

}

此类定义了一个doit方法,打印出hello world!字符串

然后看看Java怎么用这个类:

package com.test;

public class TestHelloWorld {

/**

* @param args

*/

public static void main(String[] args) {

TestGroovyHelloWorld test = new TestGroovyHelloWorld();

test.doit();

}

}

运行一下,果然打出了hello world!

很简单吧,只要直接import就行了.hoho,而且定义一个GroovyBean比定义一个JavaBean要简单的多的多.

2.运行Groovy脚本

实际上和Groovy类差不多,只不过Groovy类是集成自GroovyObject,而Groovy脚本是集成GroovyScript的,实际看看例子吧

Groovy脚本:

package com.test;

println "$test hello world!"

也很简单,就是打出hello world!不同的时候前面加上了$test ,这个有点类似与FreeMarker的格式($test也可以写成${test}),作用也是一样,通过外部将test参数引入,可以将$test替换成一个对象.看看下面Java怎么做的吧:

public class TestMain {

/**

* @param args

*/

public static void main(String[] args) {

Binding b = new Binding();

b.setVariable("test", "Kevin");//向脚本中的$test传入对象"Kevin"

Script test = new TestScript(b);

test.run();

}

}

打印出来一看是Kevin hello world!了..

  • 动态使用Groovy

Groovy是一个动态的脚本语言,如果只是向上面那样静态的使用,那优势就少了一半,既然是动态语言,那就看看怎么动态的去使用Groovy吧

1.通过接口,动态载入并使用Groovy类

(1)、定义Java接口包含在Java中需要调用的Groovy方法


public interface IFoo {

public Object run(Object foo);

}


(2)、创建Groovy类实现该接口

class Foo implements IFoo {

public Object run(Object foo) {

println 'Hello World!'

x = 123

foo * 10

}

}

(3)、动态载入Groovy类,创建接口实例,调用接口中定义的方法

import groovy.lang.GroovyClassLoader;

import java.io.File;

public class InvokeGroovy {

public static void main(String[] args) {

ClassLoader cl = new InvokeGroovy().getClass().getClassLoader();

GroovyClassLoader groovyCl = new GroovyClassLoader(cl);

try {

Class groovyClass = groovyCl.parseClass(new File("src/Foo.groovy"));

IFoo foo = (IFoo) groovyClass.newInstance();

System.out.println(foo.run(new Integer(2)));

} catch (Exception e) {

e.printStackTrace();

}

}

}

上面的方法是通过定义好接口来动态载入,如果没有接口怎么办...办法还是有的,那就是传说中的反射..Groovy也支持反射哦

2.通过反射,动态载入并使用Groovy类

import groovy.lang.GroovyClassLoader;

import groovy.lang.GroovyObject;

import java.io.File;

public class DynamicGroovy {

private GroovyObject groovyObject;

public Object getProperty(String name) {

return groovyObject.getProperty(name);

}

public Object invokeScriptMethod(String scriptName, String methodName, Object[] args) {

ClassLoader parent = getClass().getClassLoader();

GroovyClassLoader loader = new GroovyClassLoader(parent);

try {

Class groovyClass = loader.parseClass(new File(scriptName));

groovyObject = (GroovyObject) groovyClass

.newInstance();

return groovyObject.invokeMethod(methodName, args);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

public static void main(String[] args) {

DynamicGroovy dynamicGroovy = new DynamicGroovy();

Object[] params = {new Integer(2)};

Object result = dynamicGroovy.invokeScriptMethod("src/Foo.groovy", "run", params);

System.out.println(result);

System.out.println(dynamicGroovy.getProperty("x"));

}

}

3.动态的载入Groovy脚本

动态载入脚本就更简单了,因为Groovy提供了一个方法evaluate,,和javascript的eval很像吧:

import groovy.lang.Binding;

import groovy.lang.GroovyShell;

public class TestEval {

public Object doit() {

Binding bb = new Binding();

bb.setVariable("test", "hello world!");

GroovyShell gs = new GroovyShell(bb);

return gs.evaluate("println test");

}

/**

* @param args

*/

public static void main(String[] args) {

TestEval te = new TestEval();

te.doit();

}

}

简单吧,通过evaluate一个字符串就行了,evaluate还支持脚本文件和类文件哦....功能很强大的.

  • Groovy与流行框架的集成

1.与Spring的集成

现在Spring的核心包就提供了与Groovy的集成了,,很好,很强大,这样就可以显示业务逻辑的动态改变了

由于Groovy的代码中也有描述Java代码的机制,因此两者合用非常容易

Spring Bean:


代码

class="org.springframework.beans.factory.groovy.GroovyFactory">

20


下面是groovy的例子:

代码

factory-bean="groovyScriptFactory"

factory-method="create">

SimpleHello.groovy


groovy文件:

代码

package org.springframework.beans.factory.groovy;

class Test implements Hello {

String sayHello() {

"hello world"

}

}

2.与webwork的集成

在WebWork2中,可以使用Groovy实现Action类来简化代码,提高编码效率

例子:

package web

import java.util.Date

import org.apache.commons.logging.Log

import org.apache.commons.logging.LogFactory

import com.opensymphony.xwork.ActionSupport

class GroovyAction extends ActionSupport {

protected final Log logger = LogFactory.getLog(getClass())

private String now

String execute() {

now = "${new Date()}"

logger.info("returning view with ${now}")

"success"

}

void setNow(String now) {

this.now = now

}

String getNow() {

now

}

}

上面的Action类是Groovy类,同样扩展ActionSupport,这里要注意:

execute()方法没有throws Exception语句,这是因为目前的Groovy还没有这个Java特性,这需要在以后的版本中增加;如果添加,编译会报错

execute()方法返回时,不要使用类似SUCCESS的常量,而是用对应的值(如"success");如果使用SUCCESS,Groovy会把它解析成类的属性,抛异常

当然,在/WEB-INF/lib目录下需要包含运行以依赖的jar文件:Groovy和ASM.

首先强烈遣责water ye同学不负责任的行为,那家伙在blog上贴了一段spring 2.0m2的test代码就了事,居然不测试一下,结果俺的spring groovy test代码折腾半天才过去。

测试代码俺就不贴了,spring的配置就够了

 1 <?xml version="1.0" encoding="GBK"?>
 2 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
 3     "http://www.springframework.org/dtd/spring-beans.dtd">
 4 <beans>
 5     <bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor" />
 6     <bean id="inlineMessenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
 7         <constructor-arg>
 8             <value>inline:
 9                     package spring.groovy;
10                     
11                     class GroovyInlineMessenger  implements Messenger{
12                         void sayHello(){
13                             System.err.println("Hello");
14                         }
15                     }
16             </value>
17         </constructor-arg>
18     </bean>
19     <bean id="messenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
20         <constructor-arg value="classpath:spring/groovy/GroovyMessenger.groovy" />
21         <property name="message" value="Hello World!" />
22     </bean>
23 </beans>


1、第5行的bean定义一定要有,估计是提前编译groovy脚本的(具体的可能啃一下源码就明白了)。

2、inlineMessenger这个bean的定义,inline一定要紧跟着<value>写,我为了美观,弄成下面两种写法都没过去。

 1     <bean id="inlineMessenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
 2         <constructor-arg>
 3             <value>
 4             inline:
 5                     package spring.groovy;
 6                     
 7                     class GroovyInlineMessenger  implements Messenger{
 8                         void sayHello(){
 9                             System.err.println("Hello");
10                         }
11                     }
12             </value>
13         </constructor-arg>
14     </bean>

1     <bean id="inlineMessenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
 2         <constructor-arg>
 3             <value>
 4             <![CDATA[inline:
 5                     package spring.groovy;
 6                     
 7                     class GroovyInlineMessenger  implements Messenger{
 8                         void sayHello(){
 9                             System.err.println("Hello");
10                         }
11                     }]]>
12             </value>
13         </constructor-arg>
14     </bean>

写成这样倒是过的

 1     <bean id="inlineMessenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
 2         <constructor-arg>
 3             <value><![CDATA[inline:
 4                     package spring.groovy;
 5                     
 6                     class GroovyInlineMessenger  implements Messenger{
 7                         void sayHello(){
 8                             System.err.println("Hello");
 9                         }
10                     }]]>
11             </value>
12         </constructor-arg>
13     </bean>

俺平时习惯让myeclipse对xml进行格式化,照这么看来,估计一不小心,按个ctrl+shift+F,好端端的spring groovy代码就过不去了,然后就慢慢找问题吧。

以上是 java与Groovy的整合 的全部内容, 来源链接: utcz.com/z/393428.html

回到顶部