在应用中,我们可以在一个Java类、一个Groovy类或者一个Groovy脚本中实现某个特定功能。之后可以在Java类、Groovy类或Groovy脚本中调用该功能。

在groovy 使用groovy类,无需做什么,直接就可以工作。我们只需要确保所依赖的类在在类路径下,要么是源码,要么是字节码。
要再groovy类中执行groovy脚本,我们可以使用,groovyShell。
要在java类中使用groovy脚本,则可以使用ScriptEngine API。
如想在java中使用groovy类,或者在groovy类中使用java类,则可以使用groovy联合编译工具

开发环境搭建

  • 使用maven管理项目
  • 依赖最新版本groovy ,groovy-all
  • 确保你的ide下载了groovy插件。本次使用idea开发

使用ide自动编译,可以帮我们省去很多手动编译的麻烦

groovy 中使用groovy类

在Groovy代码中使用一个groovy类,只需要确保该类在我们的classpath下。当我们在groovy代码中引用一个groovy类时,Groovy会以该类的名字,在我们的classpath下查找.groovy文件,如果找不到则以相同的名字查找.class文件

code

package com.xxx.groovy.service

import groovy.transform.TypeChecked
import groovy.transform.TypeCheckingMode class GroovySerice { @TypeChecked
def shoutString(String str) {
println "Printing in uppercase"
println str.toUpperCase()
println "Printing again in uppercase"
println str.toUpperCase()
} @TypeChecked
def printInReverse(String str) {
println str.reverse()
} @TypeChecked(TypeCheckingMode.SKIP)
def use(Object instance) {
if (instance instanceof String) {
println instance.length()
} else {
println instance
}
} def pickEven(n, b, block) {//传递闭包
println b
for (int i = 0; i <= n; i += 2) {
block(i)
}
}
}

在另一个groovy类中调用groovy

package com.xxx.groovy.service

class RunGroovy {
private GroovySerice groovySerice = new GroovySerice() public static void main(String[] args) {
new RunGroovy().groovySerice.shoutString("hello world")
}
}

利用联合编译使用混合使用Groovy和java

如果Groovy类是预先编译好的,那我们就可以方便地在Java中使用.class文件或JAR包。来自Java的字节码和来自Groovy的字节码,对Java而言没什么区别.

如果我们只有Groovy源代码,而非字节码,又会怎样呢?请记住,当我们的Java类依赖其他Java类时,如果没有找到字节码,javac将编译它认为必要的任何Java类。不过javac对Groovy可没这么友好。幸好groovyc支持联合编译.当我们编译Groovy代码时,它会确定是否有任何需要编译的Java类,并负责编译它们

public class AJavaClass {
{
System.out.println("Created Java Class");
} public void sayHello() { System.out.println("hello"); }
}

//groovy
new AJavaClass().sayHello()

要联合编译这两个文件,我们输入这个命令:groovyc -j AJavaClass.java
UseJavaClass.groovy -Jsource 1.6。-Jsource 1.6会把可选的选项source = 1.6发送给Java编译器。使用javap检查生成的字节码,会发现AJavaClass作为一个普通的Java类
执行以下代码

java -classpath $GROOVY_HOME/embeddable/groovy-all-2.1.0.jar:. UseJavaClass

输入如下:

Created Java Class
hello

当然我们使用ide执行执行即可

在Java中调用Groovy动态方法

每个Groovy对象都实现了GroovyObject接口,该接口有一个叫作invokeMethod()的特殊方法。该方法接受要调用的方法的名字,以及要传递的参数。在Java这一端,invokeMethod()可以用来调用Groovy中使用元编程

创建一个Groovy类,其中包含一个特殊方法——methodMissing(),当某个不存在的方法被调用时,该方法会介入

    class DynamicGroovyClass {
def methodMissing(String name, args) {
println "You called $name with ${args.join(', ')}."
args.size()
}
}

要从Java端调用我们期望的方法,可调用invokeMethod(),并将方法的名字和一个由参数组成的数组传给它

public class CallDynamicMethod {
public static void main(String[] args) {
groovy.lang.GroovyObject instance = new DynamicGroovyClass(); Object result1 = instance.invokeMethod("squeak", new Object[] {});
System.out.println("Received: " + result1); Object result2 =
instance.invokeMethod("quack", new Object[] {"like", "a", "duck"});
System.out.println("Received: " + result2);
}
}

输出结果如下:

You called squeak with .

Received: 0

You called quack with like, a, duck.

Received: 3

当然我们亦可以把groovy脚本当成一个字符串传入:

//groovy 代码
package com.xxx.logclean.services import com.google.common.collect.Lists
import org.slf4j.Logger
import org.slf4j.LoggerFactory /**
* Created by hao.su on 15/11/23.
*/
public class GroovyServiceImpl implements IGroovyService {
private Logger logger = LoggerFactory.getLogger(GroovyServiceImpl.class); @Override
Object execute(String groovyScript, Map params) {
Class<GroovyObject> groovyObjectClass = parseScript(groovyScript)
GroovyObject groovyObject
try {
groovyObject = groovyObjectClass.newInstance()
} catch (any) {
logger.error("error when execute groovyScript:{}", any)
throw new RuntimeException("error,when execute groovyScript", any)
}
ArrayList<String> list = Lists.newArrayList();
return groovyObject.invokeMethod("validate", [params, list] as Object[])
} private Class<GroovyObject> parseScript(String script) {
GroovyClassLoader loader = new GroovyClassLoader();
Class<GroovyObject> clazz = loader.parseClass(script)
clazz
}
}

java 代码

public static void main(String[] args) {
Map<String, Object> map = Maps.newHashMap();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("d", 4);
List<String> list = Lists.newArrayList(new String[]{"a", "b", "c"});
map.put("d", 5);
map.put("keys",list);
String groovyScript = "import java.util.regex.Matcher\n" +
"import java.util.regex.Pattern\n" +
"def validate(Map dataMap,List list) {\n" +
" def returnList = []\n" +
" List<String> keys = dataMap.get(\"keys\")\n" +
" for (key in keys) {\n" +
" if (dataMap.containsKey(key)) {\n" +
" String value = dataMap.get(key);\n" +
" if (key == \"userId\") {\n" +
" Pattern pattern = Pattern.compile(\"[0-9]*\")\n" +
" Matcher isNum = pattern.matcher(value);\n" +
" if (!isNum.matches()) {//过滤脏数据\n" +
" return []\n" +
" }\n" +
" }\n" +
" returnList.add(value)\n" +
" }\n" +
" }\n" +
" returnList\n" +
"}";
IGroovyService impl = new GroovyServiceImpl();
List<String> returnList = (List<String>) impl.execute(groovyScript, map);
for(String str:returnList){
System.out.println(str);
}
}

输出结果如下:

1
2
3

groovy中使用java

在Groovy中使用Java类简单且直接。如果我们想使用的Java类是JDK的一部分,可以像在Java中那样导入这些类或它们的包
如果想使用一个自己的Java类,或者不是标准JDK中的类,在Groovy中可以像在Java中那样导入它们。请确保导入了必要的包或类,或者使用类的全限定名来引用它们

public class GreetJava {
public static void sayHello() {
System.out.println("Hello Java");
}
}

UseGreetJava.groovy

//groovy
com.agiledeveloper.GreetJava.sayHello()

我们想从一个Groovy脚本中调用该方法,因此首先编译Java类GreetJava.
要运行该脚本,只需要输入groovy UseGreetJava。该脚本会顺利运行,并调用GreetJava类中的sayHello()方法

Hello Java

java 和groovy的混合使用的更多相关文章

  1. Java与groovy混编 —— 一种兼顾接口清晰和实现敏捷的开发方式

    有大量平均水平左右的"工人"可被选择.参与进来 -- 这意味着好招人 有成熟的.大量的程序库可供选择 -- 这意味着大多数项目都是既有程序库的拼装,标准化程度高而定制化场景少 开发 ...

  2. Groovy小结:java调用Groovy方法并传递参数

    Groovy小结:java调用Groovy方法并传递参数 @(JAVA总结) 1. 场景描述 在网上查了资料发现,java有三种方式调用groovy脚本.但是真正在实际的服务器环境中,嵌入groovy ...

  3. 使用 Java 执行 groovy 脚本或方法

    1. 引入依赖 <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groo ...

  4. Java执行groovy脚本的两种方式

    记录Java执行groovy脚本的两种方式,简单粗暴: 一种是通过脚本引擎ScriptEngine提供的eval(String)方法执行脚本内容:一种是执行groovy脚本: 二者都通过Invocab ...

  5. Java和Groovy脚本互相调用实例

    本实例是GODU动态脚本的一个技术简化版,演示了java调groovy,groovy又调java的运行过程. 测试用例: package com.boco.godu.integration; impo ...

  6. 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

    接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...

  7. 研究dotnet动态语言IronPython(对应Java的Groovy)

    Java的标配动态语言Groovy,两者搭配可以说是完美!大规模运用的项目,如:Jenkins,通过动态语言可以弥补先天系统缺陷的bug,再者就是加强自己的业务逻辑等. 那么换过dotnet上,对应的 ...

  8. Java 调用 groovy 脚本文件,groovy 访问 MongoDB

    groovy 访问 MongoDB 示例: shell.groovy package db import com.gmongo.GMongoClient import com.mongodb.Basi ...

  9. Java集成groovy之GroovyShell、GroovyScriptEngine、GroovyClassLoader

    GroovyClassLoader 用 Groovy 的 GroovyClassLoader ,动态地加载一个脚本并执行它的行为.GroovyClassLoader是一个定制的类装载器,负责解释加载J ...

随机推荐

  1. MyBatis加强(1)~缓存机制(一级缓存、二级缓存、第三方缓存技术redis、ehcache)

    一.缓存机制 使用缓存可以使应用更快地获取数据,避免频繁的数据库交互操作,尤其是在查询越多,缓存命中率越高 的情况下,缓存的作用就越明显. 1.缓存原理:Map ■ 查询时,先从缓存区查询:找到,返回 ...

  2. 深入详解Mybatis的架构原理与6大核心流程

    MyBatis 是 Java 生态中非常著名的一款 ORM 框架,目前在一线互联网大厂中应用广泛,Mybatis已经成为了一个必会框架. 如果你想要进入一线大厂,能够熟练使用 MyBatis 开发已经 ...

  3. PHP+mysql真题

    PHP+mysql真题 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. [真题215] 按要求写出SQL实现. ...

  4. 3、前端--伪元素选择器、选择器优先级、字体、背景、边框、display、盒子模型

    伪元素选择器 # 首字调整>>>:也是一种文档布局的方式 p:first-letter { font-size: 48px; /*字体大小*/ color: red; } # 在文本 ...

  5. Process Doppelg&#228;nging

    进程注入:Process Doppelgänging   攻击者可以通过Process Doppelgänging将恶意代码注入到进程中,从而逃避基于进程的防护,并且进行可能的特权提升.Process ...

  6. java Doc的生成方式

    Java Doc Javadoc命令是用来生产自己API文档的 参数信息 @author作者名 @version 版本号 @since 指明需要最早使用的JDK版本 @param参数名 @return ...

  7. Vue 源码解读(1)—— 前言

    当学习成为了习惯,知识也就变成了常识. 感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog ...

  8. MySQL是怎么保证redo log和binlog是完整的?

    摘要:WAL机制保证只要redo log和binlog保证持久化到磁盘,就能确保MySQL异常重启后,数据可以恢复. 本文分享自华为云社区<MySQL会丢数据吗?>,作者: JavaEdg ...

  9. 基于Windows系统应用的权限维持

    1.dll劫持 生成dll 通过msf将dll木马上传到目标应用程序的dll文件夹里面,然后通过msf来将木马dll名称和正常dll名称进行互换 远程开启监听,然后一旦目标机器的应用程序运行就会触发d ...

  10. 【C#基础概念】Ineterface 接口的设计原则

    接口设计方式 自顶向下 (如图所示),自底向上(发现类需要结构了就声明一个接口). 接口的作用 用来解耦.继承 接口的本质