groovy java_在java中使用groovy怎么搞

bd40ccd2c23fd7e5e1bc7e1f354a0385.png

临摹微笑

一种基于Java虚拟机的动态语言,可以和java无缝集成,正是这个特性,很多时候把二者同时使用,把groovy作为java的有效补充。对于Java程序员来说,学习成本几乎为零。同时支持DSL和其他简介的语法(例如闭包),使代码便于阅读。可以用groovy的动态特性来做规则引擎,在DB中维护脚本,业务变化的时候让应用系统动态加载。如果引入groovy在java工程中?这个很简单,不需要做别的事情,仅仅把groovy的二方包加入到pom文件中即可。例如:org.codehaus.groovygroovy-all 1.8 . 3 java和groovy混合使用的方法有几种?1、 静态编译 ,在java工程中直接写groovy的文件,然后可以在groovy的文件中引用java工程的类,这种方式能够有效的利用groovy自身的语言特性,例如闭包;2、通过 groovyShell 类直接执行脚本,例如: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 执行文件或者脚本,例如: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 来执行,例如: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中的源码如下:return parseClass(text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy" );这个是增加缓存的代码: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();下面这个是缓存的单例类,贴一下:public class GroovyScriptClassCache {private static final Map> GROOVY_SCRIPT_CLASS_CACHE = new HashMap>();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的设置大小对于大量使用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://www.mzph.cn/news/564569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 类似wm concat_oracle的wm_concat()和mysql的group_concat()合并同列变成一行的用法以及和concat()合并不同列的区别...

前言标题几乎已经说的很清楚了&#xff0c;在oracle中&#xff0c;concat()函数和 “ || ” 这个的作用是一样的&#xff0c;是将不同列拼接在一起&#xff1b;那么wm_concat()是将同属于一个组的(group by)同一个字段拼接在一起变成一行。mysql是一样的&#xff0c;只不过mysq…

试图将驱动程序添加到存储区_基于容器的块存储使用

什么是块存储&#xff1f;分布式存储系统&#xff0c;为业务与数据在集群内漂移提供了自由保障&#xff0c;满足企业对于不受约束的系统环境要求。同时&#xff0c;平台仅保存迁移被改动的数据&#xff0c;而非整体增加数据量&#xff0c;实现增量备份。魔方云块存储的功能&…

如何编译和运行C++程序?

C 和C语言类似&#xff0c;也要经过编译和链接后才能运行。那么C是如何运行的呢&#xff0c;C和C的运行步骤是一样的。我们需要留意的是C源文件的后缀&#xff0c;以及GCC 中的g命令。 下图是 C/C 代码生成可执行文件的过程&#xff1a; C源文件的后缀 C语言源文件的后缀非…

堆排序java实例_堆排序(示例代码)

前言&#xff1a;网上有很多堆排序的案例&#xff0c;我只想写自己堆排序。一&#xff1a;堆结构即&#xff1a;一个父节点最多只能有两个子节点(可以没有)&#xff0c;如下图图1图2图3 图4二&#xff1a; 数组与堆结构转换假设已知堆数组 int[] a {9,7,6,4,5,1,3,2,} 则相…

python 生成图片_python生成带有表格的图片

因为工作中需要&#xff0c;需要生成一个带表格的图片例如&#xff1a;直接在html中写一个table标签&#xff0c;然后单独把表格部分保存成图片或者是直接将excel中的内容保存成一个图片刚开始的思路&#xff0c;是直接生成一个带有table标签的html文件&#xff0c;然后将这个文…

wpf xaml突然不能自动补齐代码_Xaml+C#桌面客户端跨平台初体验

(给DotNet加星标&#xff0c;提升.Net技能)转自&#xff1a;大头BigHeadcnblogs.com/Big-Head/p/12614118.html前言随着 .NET 5的到来&#xff0c;微软在 .NET跨平台路上又开始了一个更高的起点。回顾.NET Core近几年的成果&#xff0c;可谓是让.NET重生了一次.ASP .NET Core跨…

vc6.0mfc中单选按钮如何分组_按钮系列02-搞定按钮和选框的14个秘诀

UI 界面当中&#xff0c;各种开关、按钮、选框控件是非常常见的组件&#xff0c;它们看起来不复杂&#xff0c;但是在实际使用的时候讲究非常之多&#xff0c;它们不仅关乎体验&#xff0c;而且涉及到一些界面逻辑问题。英文中的 「Toggle」一词&#xff0c;对应的是带有短柄的…

java某个类避免findbug检查_Findbug插件静态java代码扫描工具使用

本文转自http://blog.csdn.net/gaofuqi/article/details/22679609 感谢作者FindBugs 是由马里兰大学提供的一款开源 Java静态代码分析工具。FindBugs通过检查类文件或 JAR文件&#xff0c;将字节码与一组缺陷模式进行对比从而发现代码缺陷&#xff0c;完成静态代码分析。FindBu…

4乘4方格走的路线_苏州周边4个冷门自驾游路线景点推荐

1.崇明东滩崇明东滩湿地公园有两大看点&#xff0c;一是看候鸟迁徙&#xff0c;二是看日出和星空。东滩湿地滩涂辽阔&#xff0c;低头是大片的芦苇&#xff0c;抬头是满天斑斓的云彩&#xff0c;顺着木栈道走在公园内&#xff0c;如与大自然融为一体&#xff0c;可360度将美景收…

Spring体系结构详解

Spring 框架采用分层架构&#xff0c;根据不同的功能被划分成了多个模块&#xff0c;这些模块大体可分为 Data Access/Integration、Web、AOP、Aspects、Messaging、Instrumentation、Core Container 和 Test。 Spring的体系结构如下图所示 图中包含了 Spring 框架的所有模块…

java对外查询接口注意的地方_Java接口注意点

1、接口可以多实现&#xff1a;一个实现类可以同时实现多个接口package com.qf.demo02_interface;//定义一种规则&#xff1a;interface A{public void testA();//public void fun();}//定义另一种规则interface B{public void testB();public void fun();}//实现类&#xff0c…

Spring目录结构和基础JAR包介绍

目前 Spring 框架的最新版本是 5.1.8&#xff0c;本教程是基于 Spring 的稳定版本 3.2.13 进行讲解的。读者可以通过网址 http://repo.spring.io/simple/libs-release-local/org/springframework/spring/ 下载名称为 springframework-3.2.13.RELEASE-dist.zip 的压缩包。单击此…

自定义依赖注解无效_SpringValidation用注解代替代码参数校验解析

Spring Validation概念在原先的编码中&#xff0c;我们如果要验证前端传递的参数&#xff0c;一般是在接受到传递过来的参数后&#xff0c;手动在代码中做 if-else 判断&#xff0c;这种编码方式会带来大量冗余代码&#xff0c;十分的不优雅。因此&#xff0c;推出了用注解的方…

mysql开源许可_为什么开源数据库改变许可证?

CockroachDB 是一个开源的分布式数据库&#xff0c;最近改变了代码授权&#xff0c;放弃了 Apache 许可证。一、CockroachDB 的许可证变更CockroachDB 以前的许可证是 Apache&#xff0c;代码托管在 GitHub&#xff0c;任何人都可以访问。现在的许可证改成了"商业源码许可…

Spring 依赖注入的实现

依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;和控制反转含义相同&#xff0c;它们是从两个角度描述的同一个概念。 当某个 Java 实例需要另一个 Java 实例时&#xff0c;传统的方法是由调用者创建被调用者的实例&#xff08;例如&#xff0c;使用 new…

java 静态对象语法_04.Java 语法

计算机基础知识表达式(expression)&#xff1a;Java中最基本的一个运算。比如一个加法运算表达式。12是一个表达式&#xff0c;ab也是。计算机内存的最小存储单元是字节(byte)&#xff0c;一个字节就是一个8位二进制数&#xff0c;即8个bit。它的二进制表示范围从00000000~1111…

Spring实例化Bean

在面向对象的程序中&#xff0c;要想调用某个类的成员方法&#xff0c;就需要先实例化该类的对象。在 Spring 中&#xff0c;实例化 Bean 有三种方式&#xff0c;分别是构造器实例化、静态工厂方式实例化和实例工厂方式实例化。 构造器实例化 构造器实例化是指 Spring 容器通…

Spring基于XML装配Bean

Bean 的装配可以理解为依赖关系注入&#xff0c;Bean 的装配方式也就是 Bean 的依赖注入方式。Spring 容器支持多种形式的 Bean 的装配方式&#xff0c;如基于 XML 的 Bean 装配、基于 Annotation 的 Bean 装配和自动装配等。 Spring 基于 XML 的装配通常采用两种实现方式&…

苹果php环境,苹果电脑安装PHP环境步骤-PHP问题

苹果电脑装置PHP环境步骤&#xff1a;一、起首咱们需求装置Homebrew二、终端输出饬令// 创立目次,假如你不创立过该目次sudo mkdir /usr/local/varsudo chmod 777 /usr/local/var//修正成你本人的用户名以及组,假如你不创立过该目次sudo mkdir /usr/local/sbin/sudo chown -R :…

Spring基于Annotation装配Bean

在 Spring 中&#xff0c;尽管使用 XML 配置文件可以实现 Bean 的装配工作&#xff0c;但如果应用中 Bean 的数量较多&#xff0c;会导致 XML 配置文件过于臃肿&#xff0c;从而给维护和升级带来一定的困难。 Java 从 JDK 5.0 以后&#xff0c;提供了 Annotation&#xff08;注…