`
iamzhongyong
  • 浏览: 805306 次
  • 性别: 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一个 ,最近正在找这方面的资料

相关推荐

    Java中使用Groovy的三种方式

    本文将深入探讨在Java项目中使用Groovy的三种主要方式,并阐述它们各自的优势和应用场景。 一、作为嵌入式脚本 Java 6引入了JSR 223(Scripting for the Java Platform),允许在Java程序中直接执行脚本语言。...

    groovy和Java相互调用1

    描述中提到的Groovy调用Java的过程是“无缝”的,这意味着Groovy对Java API的集成非常紧密,使得开发者可以自然地在Groovy中使用Java的功能。 Java调用Groovy类则稍微复杂一些,通常有两种主要方法: 1. **方法1:...

    Java调用Groovy,实时动态加载数据库groovy脚本

    当我们需要在Java程序中调用Groovy脚本时,可以使用以下步骤: 1. 引入Groovy库:在Java项目中添加Groovy的相关依赖,通常是`groovy-all`,确保Java能够访问Groovy运行时环境。 2. 创建GroovyClassLoader:使用这...

    SpringBoot-Gradle-Maven-Java-Groovy

    SpringBoot、Gradle、Maven、Java和Groovy是Java生态...- 在测试和配置管理中使用Groovy,如Spock测试框架和Grails配置。 理解并熟练掌握这些技术,有助于提升Java开发者的专业技能,更好地适应现代企业级开发的需求。

    hugo110-java_run_groovy-master_java_

    这暗示了该项目不仅涉及基本的Groovy语法,还可能涵盖如何在Java环境中集成Groovy,以及如何利用Groovy的灵活性来执行动态任务。 Groovy是一种基于Java平台的动态编程语言,它与Java语法相似,但提供了更简洁、灵活...

    [Groovy] Making Java Groovy 英文版

    Making Java Groovy is a practical handbook for developers who want to blend Groovy into their day to day work with Java It starts by introducing the key differences between Java and Groovy and how you...

    干货:Jenkins Pipeline调用shell、python、java、groovy脚本的正确使用姿势.doc

    例如在服务器上执行 shell 命令、运行 python 或者 java 测试代码以及使用 groovy 脚本来实现一些更为复杂的功能等等。 执行 shell 命令 在 Jenkins Pipeline 中,使用 `sh` 指令可以执行 shell 命令。例如,使用 ...

    maven配置java项目使用groovy做源码.zip

    在Java项目中使用Groovy,可以利用其灵活性和生产力优势,同时保持与现有Java代码库的兼容性。 为了使Maven能够处理Groovy源码,我们需要在`pom.xml`中添加Groovy Maven插件,例如`groovy-maven-plugin`。该插件会...

    java 动态脚本语言 精通 Groovy

    9. **Scripting in Java Applications**:Groovy可以嵌入到Java应用中作为脚本语言使用,例如在服务器端处理HTTP请求,或者作为配置文件来动态改变应用行为。 10. **持续集成与构建工具**:Groovy也是构建工具如...

    Java Groovy

    - **混合使用**:开发者可以在Java项目中引入Groovy脚本来执行特定任务,比如配置文件解析或测试脚本编写。 - **代码互操作性**:Groovy和Java之间可以直接相互调用方法和构造器,这种无缝的互操作性为项目带来了极...

    Groovy+Java混合使用例子

    Groovy环境搭建教程中的例子工程,纯Java、纯Groovy以及Java+Groovy混合 教程参考:http://blog.csdn.net/rcom10002/archive/2011/06/26/6568557.aspx

    Java调用Groovy

    Java调用Groovy是一种常见的技术,特别是在开发过程中需要动态脚本支持时。Groovy是一种基于JVM(Java Virtual Machine)的、动态类型的编程语言,它与Java有着良好的互操作性,能够无缝集成到Java项目中。这篇博客...

    java在嵌入运行groovy代码1

    Java 嵌入运行 Groovy 代码是一种常见的技术实践,特别是在需要动态脚本执行或灵活扩展功能的场景中。Groovy 是一种与 Java 兼容的动态编程语言,它的语法简洁,适合编写脚本和快速原型开发。在 Java 应用程序中运行...

    Groovy在Spring中的简单使用

    Groovy 在 Spring 中的简单使用 Groovy 是一种敏捷的动态语言,用于 Java 虚拟机,可以与 Java 代码无缝集成。它的类 Java 语法对于 Java 开发人员来说很自然,且可以作为纯粹的脚本语言使用。在 Spring 中动态使用...

    Making Java Groovy源码

    Making Java Groovy Kenneth A. Kousen 1.Easier Java 2.Closures, builders, and metaprogramming 3.Gradle for builds, Spock for testing 4.Groovy frameworks like Grails and Griffon 源码

    groovy-src-1.8.5.zip_.bzrignore_Groovy_Java 8_groovy src_lowern

    Groovy结合了脚本语言的简洁性和动态性,同时提供了静态类型的编译选项,使得它在Java开发环境中尤其受欢迎。在这个"groovy-src-1.8.5.zip"压缩包中,我们能找到Groovy 1.8.5版本的源代码,这对于学习、调试或扩展...

    Groovy脚本:Java平台的动态编程利器

    本文将详细介绍Groovy脚本的基本概念、特点、用途以及如何在Java平台中使用Groovy进行动态编程。 Groovy脚本语言以其简洁的语法、动态特性和与Java的紧密集成,在Java平台中发挥着重要作用。从动态脚本执行到构建...

    groovy programming(2006.12).pdf

    由于Groovy与Java的高度兼容性,本书特别强调了如何在Java项目中使用Groovy脚本或Groovy类。这包括如何在Java代码中调用Groovy脚本,以及如何在Groovy中调用Java类库。这种集成能力使得Groovy可以作为Java项目的脚本...

    java与groovy互相调用1

    在实际开发中,这种互操作性使开发者可以根据需求灵活选择语言,比如在配置脚本、测试代码或者复杂逻辑中使用Groovy,而在性能关键的部分使用Java。这种混合编程模式可以提高开发效率,同时保证系统的稳定性和性能。

    eclipse安装groovy插件的步骤

    为了能够在 Eclipse 中使用 Groovy 进行开发,首先需要安装 Groovy 插件。以下是详细的安装步骤: 1. **下载 GroovyEclipse.zip 文件**:访问 Groovy 的官方网站或 GitHub 仓库获取最新版本的 GroovyEclipse.zip ...

Global site tag (gtag.js) - Google Analytics