最近设计一个数据统计系统,系统中上百种数据统计维度,而且这些数据统计的指标可能随时会调整.如果基于java编码的方式逐个实现数据统计的API设计,工作量大而且维护起来成本较高;最终确定为将"数据统计"的计算部分单独分离成脚本文件(javascript,或者Groovy),非常便捷了实现了"数据统计Task" 与 "数据统计规则(计算)"解耦,且可以动态的加载和运行的能力.顺便对JAVA嵌入运行Groovy脚本做个备忘.
Java中运行Groovy,有三种比较常用的类支持:GroovyShell,GroovyClassLoader以及Java-Script引擎(JSR-223).
1) GroovyShell: 通常用来运行"script片段"或者一些零散的表达式(Expression)
2) GroovyClassLoader: 如果脚本是一个完整的文件,特别是有API类型的时候,比如有类似于JAVA的接口,面向对象设计时,通常使用GroovyClassLoader.
3) ScriptEngine: JSR-223应该是推荐的一种使用策略.规范化,而且简便.
一.GroovyShell代码样例
1) 简单的表达式执行,方法调用
-
-
-
-
-
publicstaticvoidevalScriptText()throwsException{
-
-
Bindingbinding=newBinding();
-
GroovyShellshell=newGroovyShell(binding);
-
-
binding.setVariable("name","zhangsan");
-
shell.evaluate("println'HelloWorld!Iam'+name;");
-
-
shell.evaluate("date=newDate();");
-
Datedate=(Date)binding.getVariable("date");
-
System.out.println("Date:"+date.getTime());
-
-
-
Longtime=(Long)shell.evaluate("deftime=date.getTime();returntime;");
-
System.out.println("Time:"+time);
-
binding.setVariable("list",newString[]{"A","B","C"});
-
-
StringjoinString=(String)shell.evaluate("defcall(){returnlist.join('-')};call();");
-
System.out.println("Arrayjoin:"+joinString);
-
shell=null;
-
binding=null;
-
}
2) 伪main方法执行.
-
-
-
-
publicstaticvoidevalScriptAsMainMethod(){
-
String[]args=newString[]{"Zhangsan","10"};
-
Bindingbinding=newBinding(args);
-
GroovyShellshell=newGroovyShell(binding);
-
shell.evaluate("staticvoidmain(String[]args){if(args.length!=2)return;println('Hello,Iam'+args[0]+',age'+args[1])}");
-
shell=null;
-
binding=null;
-
}
3) 通过Shell运行具有类结构的Groovy脚本
-
-
-
-
-
publicstaticvoidevalScriptTextFull()throwsException{
-
StringBufferbuffer=newStringBuffer();
-
-
buffer.append("classUser{")
-
.append("Stringname;Integerage;")
-
-
.append("StringsayHello(){return'Hello,Iam'+name+',age'+age;}}\n");
-
-
buffer.append("defuser=newUser(name:'zhangsan',age:1);")
-
.append("user.sayHello();");
-
-
Bindingbinding=newBinding();
-
GroovyShellshell=newGroovyShell(binding);
-
Stringmessage=(String)shell.evaluate(buffer.toString());
-
System.out.println(message);
-
-
StringmainMethod="staticvoidmain(String[]args){defuser=newUser(name:'lisi',age:12);print(user.sayHello());}";
-
shell.evaluate(mainMethod);
-
shell=null;
-
}
4) 方法执行和分部调用
-
-
-
-
-
publicstaticvoidevalScript()throwsException{
-
Bindingbinding=newBinding();
-
GroovyShellshell=newGroovyShell(binding);
-
-
-
Scriptscript=shell.parse("defjoin(String[]list){returnlist.join('--');}");
-
StringjoinString=(String)script.invokeMethod("join",newString[]{"A1","B2","C3"});
-
System.out.println(joinString);
-
-
-
-
script=shell.parse("staticvoidmain(String[]args){i=i*2;}");
-
script.setProperty("i",newInteger(10));
-
script.run();
-
System.out.println(script.getProperty("i"));
-
-
System.out.println(script.getBinding().getVariable("i"));
-
script=null;
-
shell=null;
-
}
二. GroovyClassLoader代码示例
1) 解析groovy文件
-
-
-
-
publicstaticvoidparse()throwsException{
-
GroovyClassLoaderclassLoader=newGroovyClassLoader(Thread.currentThread().getContextClassLoader());
-
FilesourceFile=newFile("D:\\TestGroovy.groovy");
-
ClasstestGroovyClass=classLoader.parseClass(newGroovyCodeSource(sourceFile));
-
GroovyObjectinstance=(GroovyObject)testGroovyClass.newInstance();
-
Longtime=(Long)instance.invokeMethod("getTime",newDate());
-
System.out.println(time);
-
Datedate=(Date)instance.invokeMethod("getDate",time);
-
System.out.println(date.getTime());
-
-
instance=null;
-
testGroovyClass=null;
-
}
2) 如何加载已经编译的groovy文件(.class)
-
publicstaticvoidload()throwsException{
-
GroovyClassLoaderclassLoader=newGroovyClassLoader(Thread.currentThread().getContextClassLoader());
-
BufferedInputStreambis=newBufferedInputStream(newFileInputStream("D:\\TestGroovy.class"));
-
ByteArrayOutputStreambos=newByteArrayOutputStream();
-
for(;;){
-
inti=bis.read();
-
if(i==-1){
-
break;
-
}
-
bos.write(i);
-
}
-
ClasstestGroovyClass=classLoader.defineClass(null,bos.toByteArray());
-
-
-
-
GroovyObjectinstance=(GroovyObject)testGroovyClass.newInstance();
-
Longtime=(Long)instance.invokeMethod("getTime",newDate());
-
System.out.println(time);
-
Datedate=(Date)instance.invokeMethod("getDate",time);
-
System.out.println(date.getTime());
-
-
-
bis.close();
-
bos.close();
-
instance=null;
-
testGroovyClass=null;
-
}
三. ScriptEngine
1) pom.xml依赖
-
<dependency>
-
<groupId>org.codehaus.groovy</groupId>
-
<artifactId>groovy</artifactId>
-
<version>2.1.6</version>
-
</dependency>
-
<dependency>
-
<groupId>org.codehaus.groovy</groupId>
-
<artifactId>groovy-jsr223</artifactId>
-
<version>2.1.6</version>
-
</dependency>
2) 代码样例
-
publicstaticvoidevalScript()throwsException{
-
ScriptEngineManagerfactory=newScriptEngineManager();
-
-
ScriptEngineengine=factory.getEngineByName("groovy");
-
System.out.println(engine.toString());
-
assertengine!=null;
-
-
Bindingsbinding=engine.createBindings();
-
binding.put("date",newDate());
-
-
engine.eval("defgetTime(){returndate.getTime();}",binding);
-
engine.eval("defsayHello(name,age){return'Hello,Iam'+name+',age'+age;}");
-
Longtime=(Long)((Invocable)engine).invokeFunction("getTime",null);
-
System.out.println(time);
-
Stringmessage=(String)((Invocable)engine).invokeFunction("sayHello","zhangsan",newInteger(12));
-
System.out.println(message);
-
}
需要提醒的是,在groovy中,${expression} 将会被认为一个变量,如果需要输出"$"符号,需要转义为"\$".
关于ScriptEngine更多介绍,请参考.
分享到:
相关推荐
Java 嵌入运行 Groovy 代码是一种常见的技术实践,特别是在需要动态脚本执行或灵活扩展功能的场景中。Groovy 是一种与 Java 兼容的动态编程语言,它的语法简洁,适合编写脚本和快速原型开发。在 Java 应用程序中运行...
压缩包中的`Groovy_Script`很可能包含了几个Groovy脚本文件,这些文件可能包含了示例代码,展示了如何在Java应用中嵌入Groovy脚本。文件名可能如`ScriptExample.groovy`,其中包含了具体的脚本代码,如定义函数、...
9. **Scripting in Java Applications**:Groovy可以嵌入到Java应用中作为脚本语言使用,例如在服务器端处理HTTP请求,或者作为配置文件来动态改变应用行为。 10. **持续集成与构建工具**:Groovy也是构建工具如...
此外,Groovy还与Java无缝集成,可以调用所有Java库,并且Java代码也可以直接嵌入到Groovy脚本中。 总之,Groovy脚本语言bin提供的1.6.5版本是一个全面的开发包,旨在支持开发人员在JVM上快速开发、测试和部署...
这个API在Java 6版本中得到了显著增强,为开发者提供了在Java程序中嵌入和执行脚本引擎的能力,例如JavaScript、Groovy或Rhino等。通过Java脚本API,开发者可以利用脚本语言的灵活性和简洁性,同时保持Java的系统级...
Groovy是一种动态、灵活的编程语言,它与Java高度兼容并常常被用于简化Java开发,尤其是在脚本编写和...通过`GroovyClassLoader`和`GroovyShell`,开发者可以轻松地将Groovy代码嵌入到Java应用中,实现动态行为和交互。
JSAPI是Java平台标准版(Java SE)的一部分,它允许开发者在Java程序中嵌入并执行脚本语言。JSAPI通过提供ScriptEngine接口,使得开发者能够轻松地调用不同脚本引擎,如JavaScript、Groovy或Rhino,执行脚本代码。...
5. 嵌入式脚本:由于`groovy-all.jar`的存在,你可以直接在Java应用中执行Groovy脚本,无需额外的配置或环境。 6. 极简的语法:Groovy的语法比Java更简洁,例如,不需要分号和大括号来结束语句和块。 对于...
随着Groovy的更新迭代,后续版本提供了更多特性,如GroovyShell、GroovyScriptEngine等,用于运行和解释Groovy脚本,以及 Grape(依赖管理) 和 GPars(并行和并发处理库)等实用工具。 在实际开发中,Groovy常用于...
通过阅读并实践"Using-Groovy-scriptlets-inside-a-docx-document.pdf"文档,你将能够掌握如何在Word文档中嵌入和运行Groovy脚本,从而提升你的文档处理体验。无论你是企业用户还是个人开发者,这个技巧都值得你学习...
字符串插值允许在字符串中嵌入Groovy表达式,这些表达式在字符串被处理时会被计算并替换为相应的值。插值表达式由${}包围,也可以使用$前缀直接插入表达式。 7. **内插闭包表达式的特殊情况** 在特定情况下,...
此外,Groovy与Java完全兼容,可以无缝地与Java代码混合编写,这意味着你可以在同一个项目中使用Java类和Groovy脚本。 Groovy 1.8.6中的一些关键特性包括: 1. **动态类型**:Groovy默认采用动态类型,这意味着...
- **使用Groovy脚本**:在Java程序中可以通过`groovy.lang.GroovyShell`或`groovy.lang.GroovyClassLoader`来执行Groovy脚本。 #### 六、总结 虽然“Java脚本编程”这个说法可能并不准确,但在Java中确实可以通过...
Groovy提供了多种运行方式,包括通过命令行使用`groovysh`或`groovy`命令执行脚本,或者使用`groovyc`编译器将Groovy脚本编译成Java字节码。此外,Groovy还集成了常见的构建工具如Ant和Maven,使得集成到现有的构建...
Groovy支持模块化编程,可以通过import语句导入其他Groovy脚本或Java类。同时,Groovy允许以脚本的形式运行代码,这意味着可以快速执行代码片段而无需编写完整的类和方法。 元编程: Groovy提供了强大的元编程能力...
这使得Groovy成为快速开发、脚本编写以及构建自动化等任务的理想选择。 GroovyEclipse是一款强大的Eclipse插件,专门为Groovy开发者设计。它为Eclipse IDE带来了对Groovy语言的全面支持,包括语法高亮、代码提示、...
Groovy是一种基于Java平台的动态脚本语言,它在设计时考虑了简洁性和生产力的提升。Groovy之所以受到青睐,主要是因为它比Java更加抽象和高效,允许开发者编写更少的代码来实现同样的功能。以下是对Groovy的一些核心...
4. **GroovyShell与GroovyScriptEngine**:这两个工具允许你在运行时执行Groovy代码,是学习和调试Groovy脚本的好帮手。 5. **GString与字符串操作**:Groovy的GString是一种可以包含表达式的字符串,它允许你在...