java与Groovy的整合(I)

news/2024/7/7 1:29:04

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与流行框架的集成
...

http://www.niftyadmin.cn/n/3641956.html

相关文章

设计模式:中介者模式(Mediator)

定 义:用一个中介对象来封装一系列对象的交互。中介者使各个对象不需要显示地相互作用,从而耦合松散,而且可以独立的改变他们之间的交互。 结构图: Mediator类,抽象中介者类 abstract class Mediator{public abstrac…

java与Groovy的整合(II)

Groovy与流行框架的集成 1.与Spring的集成 现在Spring的核心包就提供了与Groovy的集成了,,很好,很强大,这样就可以显示业务逻辑的动态改变了 由于Groovy的代码中也有描述Java代码的机制,因此两者合用非常容易 Spring Bean: 代码 class"org.springframework.bea…

【Leetcode】1844. Replace All Digits with Characters

题目地址: https://leetcode.com/problems/replace-all-digits-with-characters/ 给定一个字符串sss,其只含小写字母和数字,并且偶数下标的全是小写字母,奇数下标的全是单个数字。要求将sss中的数字都改为其前一个字母加上这个数…

【Leetcode】848. Shifting Letters

题目地址: https://leetcode.com/problems/shifting-letters/ 给定一个小写英文字母的长nnn字符串sss,和一个等长的非负整数数组AAA,要求先将s[0]s[0]s[0]字符增加A[0]A[0]A[0]这么多数,然后将s[0:1]s[0:1]s[0:1]增加A[1]A[1]A[…

实现主成分分析与白化

在这一节里,我们将总结PCA,ZCA白化算法,并描述如何使用高效的线性代数库来实现它们。 首先,我们需要确保数据的均值(近似)为零。对于自然图像,我们通过减去每个图像块(patch)的均值(近似地&…

实战 Groovy: Groovy:Java 程序员的 DSL

实战 Groovy: Groovy:Java 程序员的 DSL 用 Groovy 编写更少的代码,完成更多的工作Scott Davis, 创始人, ThirstyHead.comScott Davis 是国际知名作家、演讲家、软件开发人员。他是 ThirstyHead.com 的创始人,这是一家 Groovy 和 Grails 培训…

【Leetcode】1106. Parsing A Boolean Expression

题目地址: https://leetcode.com/problems/parsing-a-boolean-expression/ 给定一个表达式,该表达式是个类似于前缀表达式的布尔表达式,其中t代表true,f代表false,其定义是递归的: 1、单个t或者f是个表达…

通过与Java的比较,迅速掌握Groovy

Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18) 在前几篇文章中,我已经向大家介绍了Groovy是什么,学习Groovy的重要性等内容,还不了解Groovy的朋友不妨去看看我Blog中的 Groovy分类…