`
iamzhongyong
  • 浏览: 804441 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

在java中使用groovy怎么搞 (java and groovy)

    博客分类:
  • java
阅读更多

什么是groovy?

一种基于Java虚拟机的动态语言,可以和java无缝集成,正是这个特性,很多时候把二者同时使用,把groovy作为java的有效补充。对于Java程序员来说,学习成本几乎为零。同时支持DSL和其他简介的语法(例如闭包),使代码便于阅读。可以用groovy的动态特性来做规则引擎,在DB中维护脚本,业务变化的时候让应用系统动态加载。

 

如果引入groovy在java工程中?

这个很简单,不需要做别的事情,仅仅把groovy的二方包加入到pom文件中即可。例如:

1
2
3
4
5
<dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>1.8.3</version>
</dependency>

 

java和groovy混合使用的方法有几种?

 

1、静态编译,在java工程中直接写groovy的文件,然后可以在groovy的文件中引用java工程的类,这种方式能够有效的利用groovy自身的语言特性,例如闭包;

 

2、通过groovyShell类直接执行脚本,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
package groovy_dsl.shell;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class GroovyShellEx {
        public static void main(String[] args) {
                Binding bind = new Binding();
                bind.setVariable("name""iamzhongyong");
                bind.setVariable("age""25");       
                GroovyShell shell = new GroovyShell(bind);               
                Object obj = shell.evaluate("str = name+age;return str");               
                System.out.println(obj);
        }
}

 

3、通过groovyScriptEngine执行文件或者脚本,例如:

1
2
3
4
5
6
7
8
9
package groovy_dsl.script;
import groovy.util.GroovyScriptEngine;
public class ScriptEngine {
        public static void main(String[] args) throws Exception {
                GroovyScriptEngine engine = new GroovyScriptEngine("");           
                Object obj = engine.run("src/main/java/groovy_dsl/script/script_test.groovy""iamzhongyong");            
                System.out.println(obj);
        }
}

 

​4、通过GroovyClassLoader来执行,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package groovy_dsl.classloader;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;
import java.io.IOException;
public class GroovyClassLoaderEx {
 
        public static void main(String[] args) throws Exception, IOException {
                GroovyClassLoader loader = new GroovyClassLoader();
 
                for(int i=0;i<100;i++){
                        Class<?> clazz = loader.parseClass(new File("src/main/java/groovy_dsl/classloader/UserDO.groovy"));
 
                        GroovyObject clazzObj = (GroovyObject)clazz.newInstance();
 
                        clazzObj.invokeMethod("setName""iamzhongyong");
                        clazzObj.invokeMethod("setSex""Boy");
                        clazzObj.invokeMethod("setAge""26");
 
                        System.out.println(clazzObj.invokeMethod("getAllInfo"null));
                }
 
        }
}

 

使用groovy尤其需要主要的问题?

通过看groovy的创建类的地方,就能发现,每次执行的时候,都会新生成一个class文件,这样就会导致JVM的perm区持续增长,进而导致FullGCc问题,解决办法很简单,就是脚本文件变化了之后才去创建文件,之前从缓存中获取即可。

groovy中的源码如下:

1
return parseClass(text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy");

这个是增加缓存的代码:

1
2
3
4
5
6
7
8
9
10
11
12
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(GroovyScriptExecute.class.getClassLoader());
Class<?> groovyClass = null;
String classKey = String.valueOf(scriptClass.hashCode());
//先从缓存里面去Class文件
if(GroovyScriptClassCache.newInstance().containsKey(classKey)){
    groovyClass = GroovyScriptClassCache.newInstance().getClassByKey(classKey);
}else{
    groovyClass = groovyClassLoader.parseClass(scriptClass);
    GroovyScriptClassCache.newInstance().putClass(classKey, groovyClass);
}
 
GroovyObject go = (GroovyObject)groovyClass.newInstance();

下面这个是缓存的单例类,贴一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class GroovyScriptClassCache {
    private static final Map<String/*class文件的描述*/,Class<?>> GROOVY_SCRIPT_CLASS_CACHE = new HashMap<String,Class<?>>();
     
    private GroovyScriptClassCache(){}
     
    private static GroovyScriptClassCache instance = new GroovyScriptClassCache();
     
    public static GroovyScriptClassCache newInstance(){
        return instance;
    }
     
    public Class<?> getClassByKey(String key){
        return GROOVY_SCRIPT_CLASS_CACHE.get(key);
    }  
    public void putClass(String key,Class<?> clazz){
        GROOVY_SCRIPT_CLASS_CACHE.put(key, clazz);
    }  
    public boolean containsKey(String key){
        return GROOVY_SCRIPT_CLASS_CACHE.containsKey(key);
    }  
}

 

为啥要每次new一个GroovyClassLoader,而不是所有的脚本持有一个?

因为如果脚本重新加载了,这时候就会有新老两个class文件,如果通过一个classloader持有的话,这样在GC扫描的时候,会认为老的类还在存活,导致回收不掉,所以每次new一个就能解决这个问题了。

 

注意CodeCache的设置大小(来自:http://hellojava.info/

对于大量使用Groovy的应用,尤其是Groovy脚本还会经常更新的应用,由于这些Groovy脚本在执行了很多次后都会被JVM编译为native进行优化,会占据一些CodeCache空间,而如果这样的脚本很多的话,可能会导致CodeCache被用满,而CodeCache一旦被用满,JVM的Compiler就会被禁用,那性能下降的就不是一点点了。

Code Cache用满一方面是因为空间可能不够用,另一方面是Code Cache是不会回收的,所以会累积的越来越多(其实在不采用groovy这种动态更新/装载class的情况下的话,是不会太多的),所以解法一可以是增大code cache的size,可通过在启动参数上增加-XX:ReservedCodeCacheSize=256m(Oracle JVM Team那边也是推荐把code cache调大的),二是启用code cache的回收机制(关于Code Cache flushing的具体策略请参见此文),可通过在启动参数上增加:-XX:+UseCodeCacheFlushing来启用。

 

参考:

http://groovy.codehaus.org/Chinese+Home

http://hellojava.info/

https://github.com/iamzhongyong/groovy_dsl (代码在这里)

 

0
0
分享到:
评论
7 楼 readxuxuegang 2017-09-17  
博主你好。如果groovy的代码是保存在数据库里,不是文件,这样怎么跟spring整合的
6 楼 di1984HIT 2014-02-16  
有机会看看吧。
5 楼 非法用户 2014-01-17  
yixiandave 写道
非法用户 写道
用GroovyShell直接执行一段groovy代码,过不了多久的确会造成Perm Generation爆满
先用script = shell.parse生成script,缓存起来可以解决

直接创建的groovy类不会出现这种情况吧

直接创建的Groovy类不会,GroovyShell动态执行一段groovy脚本是相当于在动态创建一个class,执行一次创建一个,所以才会导致Perm Generation爆满
4 楼 yixiandave 2014-01-16  
非法用户 写道
用GroovyShell直接执行一段groovy代码,过不了多久的确会造成Perm Generation爆满
先用script = shell.parse生成script,缓存起来可以解决

直接创建的groovy类不会出现这种情况吧
3 楼 非法用户 2014-01-16  
用GroovyShell直接执行一段groovy代码,过不了多久的确会造成Perm Generation爆满
先用script = shell.parse生成script,缓存起来可以解决
2 楼 yixiandave 2014-01-16  
引用
通过看groovy的创建类的地方,就能发现,每次执行的时候,都会新生成一个class文件

这是个什么情况?直接创建的groovy文件也有这种问题吗?2.0以后有没有修复?
1 楼 JavaLanguageFun 2014-01-16  
mark一个 ,最近正在找这方面的资料

相关推荐

    电动车上牌管理系统 SSM毕业设计 附带论文.zip

    电动车上牌管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B

    tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl

    tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl

    【eclipse和idea两个版本运行源码】基于Java Swing +mysql 实现的网吧管理系统

    一、项目简介 本项目是一套基于Java Swing 开发的网吧管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,确保可以运行! 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 二、技术实现 ​后台技术:java swing ​数据库:MySQL ​数据库连接池:c3p0 三、系统主要功能 用户登录: 分为 普通用户和管理员 两种角色 菜单模块:上机,下机, 系统设置:管理员设置,会员设置,计费设置, 退出系统 管理模块:增加会员,删除会员,信息修改,信息查询 视图模块:主页视图,在线用户,统计视图, 统计报表模块:人数报表,收入报表 帮助模块:联系我们,关于系统 详见:https://blog.csdn.net/weixin_43860634/article/details/125247764

    pc-dmis软件脚本-输出Excel格式报告

    使用软件自带的basic脚本编辑制作的脚本 低版本软件无法输出Excel报告,可以通过脚本方式实现这一功能

    【java毕业设计】校园失物招领系统源码(springboot+vue+mysql+说明文档).zip

    项目经过测试均可完美运行! 环境说明: 开发语言:java jdk:jdk1.8 数据库:mysql 5.7+ 数据库工具:Navicat11+ 管理工具:maven 开发工具:idea/eclipse

    基于java的网上电子书店h答辩PPT.pptx

    基于java的网上电子书店h答辩PPT.pptx

    基于微信小程序的微信小程序校园失物招领答辩PPT.pptx

    基于微信小程序的微信小程序校园失物招领答辩PPT.pptx

    基于java的基于Java的学生综合测评管理系统答辩PPT.pptx

    基于java的基于Java的学生综合测评管理系统答辩PPT.pptx

    pandas-2.1.4-cp39-cp39-win_amd64.zip

    pandas whl安装包,对应各个python版本和系统(具体看资源名字),找准自己对应的下载即可! 下载后解压出来是已.whl为后缀的安装包,进入终端,直接pip install pandas-xxx.whl即可,非常方便。 再也不用担心pip联网下载网络超时,各种安装不成功的问题。

    判断题 - 题目列表 - 图-练习题集飒飒阿萨

    springboot体育器材管理系统(附源码+数据库)71175

    管理员功能: 用户管理:管理员可以管理用户账户,包括审核新注册用户、禁用违规用户、重置密码等操作。 器材管理:管理员可以管理器材的信息,包括添加新器材、编辑器材详情、设定器材规则和限制等。 器材预约与借还管理:管理员可以处理用户的器材预约请求,确认或调整预约时间,并记录借还操作。 库存管理:管理员可以监控器材库存情况,及时补充不足的器材并处理损坏或报废的器材。 数据统计与报表:管理员可以分析系统的使用情况和借还记录,生成数据统计报表以了解器材使用情况和借还频率等。 系统设置与维护:管理员可以进行系统设置,包括配置器材规则、设定可用时间段、备份数据、优化系统性能等。 消息通知与提醒:管理员可以向用户发送消息通知,如器材预约成功、归还提醒、系统更新通知等。

    Jira插件安装包Dynamic-forms

    Jira插件安装包Dynamic-forms

    pandas-2.1.4-cp311-cp311-win_amd64.zip

    pandas whl安装包,对应各个python版本和系统(具体看资源名字),找准自己对应的下载即可! 下载后解压出来是已.whl为后缀的安装包,进入终端,直接pip install pandas-xxx.whl即可,非常方便。 再也不用担心pip联网下载网络超时,各种安装不成功的问题。

    少儿图形化scratch编程作品源码集100个

    Scratch是一款由麻省理工学院(MIT)的“终身幼儿园团队”开发的图形化编程工具,专为儿童设计,旨在帮助他们学习编程思维和逻辑能力。

    基于java的学生就业管理系统答辩PPT.pptx

    基于java的学生就业管理系统答辩PPT.pptx

    课设毕设基于SpringBoot+Vue的旅游门票信息系统设计与实现源码可运行.zip

    本压缩包资源说明,你现在往下拉可以看到压缩包内容目录 我是批量上传的基于SpringBoot+Vue的项目,所以描述都一样;有源码有数据库脚本,系统都是测试过可运行的,看文件名即可区分项目~ |Java|SpringBoot|Vue|前后端分离| 开发语言:Java 框架:SpringBoot,Vue JDK版本:JDK1.8 数据库:MySQL 5.7+(推荐5.7,8.0也可以) 数据库工具:Navicat 开发软件: idea/eclipse(推荐idea) Maven包:Maven3.3.9+ 系统环境:Windows/Mac

    大学志愿填报系统.zip

    随着社会对志愿服务活动的日益重视,各大高校也纷纷参与到志愿服务的行列中。为了更好地管理和记录志愿者活动,提高志愿服务的质量和效率,我们开发了这款大学志愿服务系统。 该系统主要包括多个功能模块,如信息管理、活动管理、学生管理等。信息管理模块允许学校管理员录入、修改和删除学校的基本信息,包括学校账号、名称、联系电话、地址、特色以及办学理念等,确保信息的准确性和完整性。活动管理模块则用于记录和管理志愿者活动的相关信息,包括活动的名称、时间、地点、参与人员等,方便志愿者进行报名和签到。 此外,系统还提供了学生管理模块,用于记录学生的志愿服务经历和表现,为学生参与志愿服务提供便利。同时,系统还支持照片上传和展示功能,通过展示志愿者活动的照片,让更多人了解和关注志愿服务事业。 整个系统界面简洁明了,操作便捷,功能强大。通过使用该系统,高校可以更加高效地管理和记录志愿者活动,提高志愿服务的整体水平。同时,该系统也为广大志愿者提供了一个展示自我、服务社会的平台。

    turbo均衡算法研究

    turbo均衡算法研究

    静态编译的Qt6.7.3(win10+MSVC2022+openssl+静态运行时) part01

    https://blog.csdn.net/aggs1990/article/details/143491823 静态编译的Qt6.7.3(win10+MSVC2022+openssl+静态运行时) 压缩包比较大,这是第一部分

    tornado-6.4b1-cp38-abi3-musllinux_1_1_i686.whl

    tornado-6.4b1-cp38-abi3-musllinux_1_1_i686.whl

Global site tag (gtag.js) - Google Analytics