Java中使用Groovy的三种方式
2015-06-11 11:57
861 查看
一直想抽些时间回顾一下Groovy,非常感谢Groovy,虽然只使用了其很小一部分功能,却给项目运行带来了极大的便利。
该博客用于帮助那些需要在Java中集成Groovy的童鞋们。
一.Groovy简单了解
1.简介
Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。
Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。
有人说,Groovy 是下一代的Java语言,不是说Groovy会替代Java,读者如果看过Java8 之 lambda表达式 与 Stream,不难发现lambda和Groovy中的闭包非常相似,Stream也融入了Groovy的思想,所以Java会越来越像Groovy。
2.基本特性
(1). 构建在强大的Java语言之上 并 添加了从Python,Ruby和Smalltalk等语言中学到的 诸多特征,例如动态类型转换、闭包和元编程(metaprogramming)支持。。
(2).为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
(3). 支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于阅读和维护。
(4).受检查类型异常(Checked Exception)也可以不用捕获。
(5). Groovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变得非常简单。
(6).在开发Web,GUI,数据库或控制台程序时 通过 减少框架性代码 大大提高了开发者的效率。
(7).支持单元测试和模拟(对象),可以 简化测试。
(8).无缝集成 所有已经存在的 Java对象和类库。
(9).直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。
(10).支持函数式编程,不需要main函数。
(11).一些新的运算符。
(12).默认导入常用的包。
(13).断言不支持jvm的-ea参数进行开关。
(14).支持对对象进行布尔求值。
(15).类不支持default作用域,且默认作用域为public。
(16).groovy中基本类型也是对象,可以直接调用对象的方法。
二.Java中使用Groovy的三种方式
注:该Maven项目需要加入groovy-all包的依赖,这里使用的是最新的2.4.3版本。Eclipse中最好安装groovy的插件,便于调试。
1.使用GroovyShell执行groovy脚本
(1).通过evaluate方法执行groovy片段
GroovyShell类提供一个evaluate方法,可直接运行一段字符串标示的groovy片段,如
是不是很方便
,GroovyShell的evaluate方法非常类似于Js的eva方法,可执行一段字符串。
(2).通过evaluate方法调用groovy脚本文件
首先新建一个Groovy文件:GroovyShell_1_1.groovy,里面有一个无参的方法sayHello,并在最后调用该方法。
在Java中就可以直接调用这个groovy文件执行了,方法如下:
第一行是 方法sayHello输出的,第二行是sayHello方法的返回值
当然,你可以传一个参数给Groovy文件并执行,新建GroovyShell_1_1.groovy,提供一个传参的sayHello方法,如:
在Java中使用Groovy提供的Binding类来绑定参数
是不是很简单
,但evaluate方法提供的作用不止这些,查官方API你会发现
evaluate方法还可以执行GroovyCodeSource(Groovy提供的包装类),或者 从互联网上执行一段脚本,还可以从输入流来执行相应的groovy等等。种类很多,大家有兴趣可以去研究。
2.通过GroovyClassLoader动态加载Groovy Class
我们比较熟悉Java的ClassLoader类加载器,当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。而GroovyClassLoader,顾名思义,就是用来加载Groovy类的加载器,想更深入了解,请参考Groovy深入探索——Groovy的ClassLoader体系。
通过GroovyClassLoader执行Groovy的方法如下:
首先新建了Groovy Class
在Tool_GroovyShell_2中就可以加载该Groovy Class了
其方式和Java中类的加载反射类似,这里不再熬述。需要注意的是,GroovyClassLoader与Java中的加载器一样,同一个类名的类只能加载一次,如果想再次加载,必须调用GroovyClassLoader的clearCache()方法移除所有已经加载的Groovy Class,详细文档见Groovy在线文档。
运行结果:
第一行为GroovyShell_2.groovy的sayHello(...)方法中内部的输出,第二行为其返回的字符串。
3.使用GroovyScriptEngine脚本引擎加载Groovy脚本
GroovyScriptEngine从指定的位置(文件系统,URL,数据库等等)加载Groovy脚本,并且随着脚本变化可重新加载它们。和GroovyShell一样,GroovyScriptEngine也可以传进变量值返回脚本的计算结果。这样我们可以把一些可用的计算公式或计算条件写入Groovy脚本中来执行应用计算。当这些公式或计算条件变更时,我们可更方便地进行更改计算。
从文件夹中加载Groovy脚本的例子如下:
首先在com.juxinli.groovy.shell包中新建三个groovy script
使用GroovyScriptEngine从com.juxinli.groovy.shell包中加载、运行这些script
运行结果:
GroovyScriptEngine的构造的方法有很多,可以参考Groovy在线文档
粗浅的回顾了一下,发现还有很多可以深入的地方,大家有好的 Groovy 应用 与发现,欢迎一起讨论、学习。
附源码下载:
java_groovy项目
csdn下载地址
Java中使用Groovy的三种方式
GitHub下载地址
参考&引用:
Groovy百度百科
Groovy入门教程
Groovy在线文档
groovy 三种运用
java中直接调用groovy的类
在Java里整合Groovy脚本的一个陷阱
Groovy深入探索——Groovy的ClassLoader体系
ClassLoader 详解及用途(写的不错)
Java中运行动态脚本 如Groovy
该博客用于帮助那些需要在Java中集成Groovy的童鞋们。
一.Groovy简单了解
1.简介
Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。
Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。
有人说,Groovy 是下一代的Java语言,不是说Groovy会替代Java,读者如果看过Java8 之 lambda表达式 与 Stream,不难发现lambda和Groovy中的闭包非常相似,Stream也融入了Groovy的思想,所以Java会越来越像Groovy。
2.基本特性
(1). 构建在强大的Java语言之上 并 添加了从Python,Ruby和Smalltalk等语言中学到的 诸多特征,例如动态类型转换、闭包和元编程(metaprogramming)支持。。
(2).为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
(3). 支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于阅读和维护。
(4).受检查类型异常(Checked Exception)也可以不用捕获。
(5). Groovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变得非常简单。
(6).在开发Web,GUI,数据库或控制台程序时 通过 减少框架性代码 大大提高了开发者的效率。
(7).支持单元测试和模拟(对象),可以 简化测试。
(8).无缝集成 所有已经存在的 Java对象和类库。
(9).直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。
(10).支持函数式编程,不需要main函数。
(11).一些新的运算符。
(12).默认导入常用的包。
(13).断言不支持jvm的-ea参数进行开关。
(14).支持对对象进行布尔求值。
(15).类不支持default作用域,且默认作用域为public。
(16).groovy中基本类型也是对象,可以直接调用对象的方法。
二.Java中使用Groovy的三种方式
注:该Maven项目需要加入groovy-all包的依赖,这里使用的是最新的2.4.3版本。Eclipse中最好安装groovy的插件,便于调试。
1.使用GroovyShell执行groovy脚本
(1).通过evaluate方法执行groovy片段
GroovyShell类提供一个evaluate方法,可直接运行一段字符串标示的groovy片段,如
// 调用evaluate方法直接执行一段Groovy public static void testGroovy1() throws CompilationFailedException, IOException { GroovyShell groovyShell = new GroovyShell(); groovyShell.evaluate("println 'My First Groovy shell.'"); }运行该方法输出如下:
My First Groovy shell.
是不是很方便
,GroovyShell的evaluate方法非常类似于Js的eva方法,可执行一段字符串。
(2).通过evaluate方法调用groovy脚本文件
首先新建一个Groovy文件:GroovyShell_1_1.groovy,里面有一个无参的方法sayHello,并在最后调用该方法。
// 不带参数的groovy方法 def sayHello() { println 'Hello World.' // 如果不写return, groovy方法的默认最后一行为 方法的返回值 //return "GroovyShell_1中的sayHello()方法的返回值" "GroovyShell_1中的sayHello()方法的返回值" } // 运行groovy方法 sayHello()
在Java中就可以直接调用这个groovy文件执行了,方法如下:
// 调用GroovyShell_1_1 public static void testGroovy2() throws CompilationFailedException, IOException { GroovyShell groovyShell = new GroovyShell(); Object result = groovyShell.evaluate(new File("src/main/java/com/juxinli/groovy/GroovyShell_1_1.groovy")); logger.info(result.toString()); }运行结果如下:
Hello World. 2015-06-10 18:23:27 [main] INFO tool.Tool_GroovyShell_1 : GroovyShell_1中的sayHello()方法的返回值
第一行是 方法sayHello输出的,第二行是sayHello方法的返回值
当然,你可以传一个参数给Groovy文件并执行,新建GroovyShell_1_1.groovy,提供一个传参的sayHello方法,如:
// 带参数的groovy方法 def sayHello(name) { println "Hello " + name + "." // 如果不写return, groovy方法的默认最后一行为 方法的返回值 //return "GroovyShell_1中的sayHello()方法的返回值" "GroovyShell_1中的sayHello(name)方法的返回值" } // 运行groovy方法 sayHello(name)
在Java中使用Groovy提供的Binding类来绑定参数
// 调用GroovyShell_1_2 public static void testGroovy3() throws CompilationFailedException, IOException { // 调用带参数的groovy shell时,使用bind绑定数据 Binding binding = new Binding(); binding.setProperty("name", "Juxinli"); GroovyShell groovyShell = new GroovyShell(binding); Object result = groovyShell.evaluate(new File("src/main/java/com/juxinli/groovy/GroovyShell_1_2.groovy")); logger.info(result.toString()); }运行结果如下:
Hello Juxinli. 2015-06-10 18:30:01 [main] INFO tool.Tool_GroovyShell_1 : GroovyShell_1中的sayHello(name)方法的返回值
是不是很简单
,但evaluate方法提供的作用不止这些,查官方API你会发现
evaluate方法还可以执行GroovyCodeSource(Groovy提供的包装类),或者 从互联网上执行一段脚本,还可以从输入流来执行相应的groovy等等。种类很多,大家有兴趣可以去研究。
2.通过GroovyClassLoader动态加载Groovy Class
我们比较熟悉Java的ClassLoader类加载器,当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。而GroovyClassLoader,顾名思义,就是用来加载Groovy类的加载器,想更深入了解,请参考Groovy深入探索——Groovy的ClassLoader体系。
通过GroovyClassLoader执行Groovy的方法如下:
首先新建了Groovy Class
package com.juxinli.groovy class GroovyShell_2 { public String sayHello(String name, String sex, int age) { println 'GroovyShell_2 的sayHello(String name, String sex, int age)方法'; return "name: " + name + ", sex: " + sex + ", age: " + age; } }
在Tool_GroovyShell_2中就可以加载该Groovy Class了
public class Tool_GroovyShell_2 { private static Logger logger = Logger.getLogger(Tool_GroovyShell_2.class); private static GroovyClassLoader groovyClassLoader = null; public static void initGroovyClassLoader() { CompilerConfiguration config = new CompilerConfiguration(); config.setSourceEncoding("UTF-8"); // 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认) groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config); } /** * 通过GroovyClassLoader加载GroovyShell_2,并反射调用其sayHello(String name, String sex, int age)方法 * */ public static String invokeSayHello(String name, String sex, int age) { String result = ""; File groovyFile = new File("src/main/java/com/juxinli/groovy/GroovyShell_2.groovy"); if (!groovyFile.exists()) { return result; } try { // 获得GroovyShell_2加载后的class Class<?> groovyClass = groovyClassLoader.parseClass(groovyFile); // 获得GroovyShell_2的实例 GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); // 反射调用sayHello方法得到返回值 Object methodResult = groovyObject.invokeMethod("sayHello", new Object[] {name, sex, age}); if (methodResult != null) { result = methodResult.toString(); } } catch (Exception e) { logger.warn("加载groovy类失败", e); } return result; } public static void main(String[] args) throws Exception { initGroovyClassLoader(); System.out.println(invokeSayHello("张三", "男", 25)); } }
其方式和Java中类的加载反射类似,这里不再熬述。需要注意的是,GroovyClassLoader与Java中的加载器一样,同一个类名的类只能加载一次,如果想再次加载,必须调用GroovyClassLoader的clearCache()方法移除所有已经加载的Groovy Class,详细文档见Groovy在线文档。
运行结果:
GroovyShell_2 的sayHello(String name, String sex, int age)方法 name: 张三, sex: 男, age: 25
第一行为GroovyShell_2.groovy的sayHello(...)方法中内部的输出,第二行为其返回的字符串。
3.使用GroovyScriptEngine脚本引擎加载Groovy脚本
GroovyScriptEngine从指定的位置(文件系统,URL,数据库等等)加载Groovy脚本,并且随着脚本变化可重新加载它们。和GroovyShell一样,GroovyScriptEngine也可以传进变量值返回脚本的计算结果。这样我们可以把一些可用的计算公式或计算条件写入Groovy脚本中来执行应用计算。当这些公式或计算条件变更时,我们可更方便地进行更改计算。
从文件夹中加载Groovy脚本的例子如下:
首先在com.juxinli.groovy.shell包中新建三个groovy script
package com.juxinli.groovy.shell def sayHello(String name) { println "Hello, " + name "GroovyShell_3_1中的sayHello()方法的返回值" } sayHello(name)GroovyShell_3_1.groovy
package com.juxinli.groovy.shell def sayHello(String name) { println "你好, " + name "GroovyShell_3_2中的sayHello()方法的返回值" } sayHello(name)GroovyShell_3_2.groovy
package com.juxinli.groovy.shell def sayHello(String name) { println "Привет, " + name "GroovyShell_3_3中的sayHello()方法的返回值" } // 运行groovy方法 sayHello(name)GroovyShell_3_3.groovy
使用GroovyScriptEngine从com.juxinli.groovy.shell包中加载、运行这些script
public class Tool_GroovyShell_3 { public static void main(String[] args) throws Exception { // GroovyScriptEngine的根路径,如果参数是字符串数组,说明有多个根路径 GroovyScriptEngine engine = new GroovyScriptEngine("src/main/java/com/juxinli/groovy/shell/"); //GroovyScriptEngine engine = new GroovyScriptEngine(new String[] {"src/main/java/com/juxinli/groovy/shell/"}); Binding binding = new Binding(); binding.setVariable("name", "juxinli"); Object result1 = engine.run("GroovyShell_3_1.groovy", binding); System.out.println(result1); Object result2 = engine.run("GroovyShell_3_2.groovy", binding); System.out.println(result2); Object result3 = engine.run("GroovyShell_3_3.groovy", binding); System.out.println(result3); } }
运行结果:
Hello, juxinli GroovyShell_3_1中的sayHello()方法的返回值 你好, juxinli GroovyShell_3_2中的sayHello()方法的返回值 Привет, juxinli GroovyShell_3_3中的sayHello()方法的返回值
GroovyScriptEngine的构造的方法有很多,可以参考Groovy在线文档
粗浅的回顾了一下,发现还有很多可以深入的地方,大家有好的 Groovy 应用 与发现,欢迎一起讨论、学习。
附源码下载:
java_groovy项目
csdn下载地址
Java中使用Groovy的三种方式
GitHub下载地址
https://github.com/leonzm/java_groovy.git
参考&引用:
Groovy百度百科
Groovy入门教程
Groovy在线文档
groovy 三种运用
java中直接调用groovy的类
在Java里整合Groovy脚本的一个陷阱
Groovy深入探索——Groovy的ClassLoader体系
ClassLoader 详解及用途(写的不错)
Java中运行动态脚本 如Groovy
相关文章推荐
- 用groovy写H2数据库的存储过程
- groovy实现JSONRPC
- Python, Ruby 与 Groovy,谁与争锋
- groovy中问号表达式需要注意的小地方
- 各语言设计思想的独特之处:C/C++、Java、Python、Objective C、Groovy
- 用Groovy实现解压一个压缩文件,并且找出以数字或者大写字母开头的.groovy文件
- Groovy语言的安装和Hello World例子
- groovy脚本导致的FullGC问题
- gradle学习——gradle、groovy、DSL初认知
- 动态调用动态语言之Java脚本API
- ChinaGroovy中国社区
- 万丈高楼平地起 - 读《PHP5+MySQL网页系统开发设计》
- com.microsoft.sqlserver.jdbc.SQLServerException: 不支持此服务器版本。目标服务器必须是 SQL Server 2000 或更高版本
- Grails 1.2 文档引擎速记
- JRuby、Rhino、Groovy和Jython性能及内存消耗的简单对比
- Groovy 函数(方法)定义 和 应用
- COBOL 式死亡 Java 是否真的即将被取代?
- ADF sequence
- Groovy Media Player 1.2.0 (.m3u) Local Buffer
- grails : 常用 grails 命令与中文解释