javagroovy
A. 在java中使用groovy怎么搞
一种基于Java虚拟机的动态语言,可以和java无缝集成,正是这个特性,很多时候把二者同时使用,把groovy作为java的有效补充。对于Java程序员来说,学习成本几乎为零。同时支持DSL和其他简介的语法(例如闭包),使代码便于阅读。可以用groovy的动态特性来做规则引擎,在DB中维护脚本,业务变化的时候让应用系统动态加载。
如果引入groovy在java工程中?
这个很简单,不需要做别的事情,仅仅把groovy的二方包加入到pom文件中即可。例如:
<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 类直接执行脚本,例如:
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<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的设置大小
对于大量使用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来启用。
B. Java程序员为什么学习Groovy
正如Groovy对Java很多特性进行的包装优化一样,基于Groovy的HttpBuilder也包裹了HttpClient,使网络编程变得更加的方便易用,下面稍微来用一个例子看一下。
寻找各种依赖的jar包有时候会让我们失去耐心,不过值得庆幸的是我们有Maven和Gradle这样的工具,可以根据配置轻松的帮我们配置好我们需要的数据。下面我们来叙述一下整个过程。
1. 创建文件夹httpbuildertest
2. 创建gradle配置文件,build.gradle,内容如下:
apply plugin: "groovy"apply plugin: "eclipse"repositories { mavenCentral()}dependencies { compile "org.codehaus.groovy:http-builder:0.4.0" compile "org.codehaus.groovy:groovy-all:2.3.3" testCompile "org.spockframework:spock-core:0.7-groovy-2.0"}
gradle我们将做另文介绍
3. 执行gralde eclipse(当然必须先安装gradle),就可以生成eclipse所需要的.classpath和.project文件,这时候就可以使用eclipse导入功能来import->Existing Projects Into WorkSpace。
4. 创建我们的一个测试,试试看是不是可以使用httpbuilder了
import groovyx.net.http.HTTPBuilderimport spock.lang.Specification;import static groovyx.net.http.Method.*import static groovyx.net.http.ContentType.*class HttpbuildLabSpec extends Specification{HTTPBuilder http = new HTTPBuilder( 'http://m.weather.com.cn' )public void testRequestWeather(){ when: def info ="" http.request( GET, JSON ) { url.path = '/data/101290401.html' headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4' response.success = { resp, json -> info = json.weatherinfo.city } response.failure = { resp -> println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}" } } then:"曲靖"==info}}
打完收工,通过这个小例子我们可以了解到这么一些内容:
(1)HTTPBuilder 是这个框架的核心类(要不然怎么和框架一个名字),构建这个类的对象的时候,指定要请求的baseUrl。
(2)request方法可以指定请求的method和返回的数据格式,method对应的是GET/PUT/POST/DELETE/HEAD几个常量,而数据格式目前有JSON/XML/HTML/BINARY/URLENC/ANY几种。
(3)一个比较有意思的地方是,在http的request方法里面,仿佛是无根之水一样突然冒出来了几个没有声明过的变量,看起来连编译也不会通过的方法,那么是如何能正常运作的呢?这个我们就要研究到Groovy的Closure(闭包)。Groovy的闭包里包含有一个delegate属性,一般来说,这个delegate里保存的是闭包使用上下文的对象引用,比如a调用了一个闭包b,则b的delegate就是a的this对象。而在HTTPBuilder对象调用request方法的时候,它把传入闭包的delegate改成了一个叫做SendDelegate的类对象(这是HTTPBuilder的内部类,他们都是用Java写的,在新版的HttpBuilder里,已经改名为RequestConfigDelegate),这个类里面,分别包含了一个叫做getHeaders()的方法,一个叫做getUrL()的方法,一个叫做getResponse()的方法。稍微思索一下我们就可以想到,Groovy里有这样的特性,如果直接使用一个识别不出来的变量,Groovy会假设它是getter的一种简写形式,自动进行补全(当然这也是DSL的常用伎俩,把方法伪装成短语),而getter并没有参数,所以其括号是可以简写的,实际上上面的代码可以写作getUrl().path = '/data/101290401.html',这样就非常符合程序员的视觉体验了。
(4)第四点罗嗦了不少,主要是为了喜欢追根问题的同学释疑,实际上整个调用还是非常的简单明快的,在request闭包里,我们通过response(记得吗,实际上就是GetResponse()),获得了一个Map结构,这个Map的内部结构实际上是Map<String,Closure>,对“success”和“failure”这两个key我们分别设置了对应的闭包,这样就完成了回调的设置,一旦方法成功或者失败,就可以调用到对应的闭包。
(5)使用了JSON作为返回格式,闭包的第二个参数就是解析好的返回body,就是一个Json对象,是可以直接用点号来访问的。当然最好不要在失败的闭包里放这个参数,一般失败的情况比较多,也许就是一个html返回,格式错误那么测试也就无法按照预期进行了。
C. java程序员为什么使用Groovy
Groovy是一门基于JVM的脚本语言。它在兼容Java语法的同时,借鉴了Ruby、Python等语言的特性,有自己一套简洁而灵活的语法。同时,运行在JVM上也意味着它也可以使用Java语言编写的库。这两点结合,让Groovy极其适合编写Java代码的测试脚本。
选择Groovy作为测试脚本的语言的原因:
Groovy基于JVM,这使我能够调用产品的Java代码,也能够调用Java标准库里的代码。除些之外,还可以通过Maven或Gradle使用大量的第三方Java库。
Groovy是动态语言,扩展了Java的容器类,提供了完善的函数式编程和元编程支持。这让我们可以写出简洁而富有表现力的代码。
Groovy提供了大量的语法糖。与Java自身繁冗的代码相比,这些语法糖大大节约了我们编写脚本的时间,减少了我的脚本的代码量。
然而,Groovy在带来上述三个优点的同时,也会带来有相应的缺点:
效率问题。Groovy作为运行在JVM上的动态语言,运行效率是低于Java的。虽然可以用@CompileStatic注解来静态编译一些类以提高效率,但这样又会失去Groovy的一些动态语言的特性。
语法过于灵活,运用不当会降低可读性与可维护性。Groovy支持元编程特性,可以在运行时动态添加方法。这一点自然可以简化代码,但也有很大的可能会降低可维护性。函数式编程与大量的语法糖会让不熟悉Groovy的人读起来一头雾水,反而降低了可读性。
D. Java和Groovy的区别
Groovy 是 JVM 的一个替代语言 — 替代 是指可以用 Groovy 在 Java 平台上进行 Java 编程,使用方式基本与使用 Java 代码的方式相同。
Groovy 的一个好处是,它的语法与 Java 语言的语法很相似。虽然 Groovy 的语法源于 Smalltalk 和 Ruby 这类语言的理念,但是可以将它想象成 Java 语言的一种更加简单、表达能力更强的变体。(在这点上,Ruby 与 Groovy 不同,因为它的语法与 Java 语法差异很大。)
E. Java程序员为什么学习Groovy
要成为好的JAVA程序员,不但需要会JAVA一种语言,还应该要会以JVM作为运行平台的其他语言,因为JVM支持下的语言在现在已经发展出很多种了,而且每种语言都有自己的优势,有些可以很简便地实现多线程编程,有些则对函数式编程有非常好的支持,而你在做项目的时候,针对不同的模块,可以使用不同的语言去实现,从而加快项目进度,因为JVM支持下的不同语言之间是很容易就能实现交互的。 望采纳!
F. Java程序员为什么学习Groovy
groovy、kotlin、scala等都是基于jvm平台的语言(都会编译成字节码),并且可以和java混合使用。
他们对java进行了不同程度的改良,语法结构、集合操作方式、更多的语法糖、泛型的支持(java是伪泛型),更好的lambda表达式语法等等。一般来讲这些语言可以大幅度提高生产效率,比如kotlin可以节省1/3的代码量。
从日常使用的角度,建议学习kotlin,当前kotlin已经被google确定为新任官方语言。如果做android开发,不至于再多学习一门语言。
G. java和groovy能混编吗
java和groovy肯定能混编,
java & groovy混编:一种最“势利”的折衷而groovy,说它是java++也不为过,因为java代码直接就可以被groovy编译, groovy完全兼容java语法。
H. groovy语言主要是用来干什么,和JAVA的区别是什么
Groovy是Java平台上设计的面向对象编程语言。这门动态语言拥有类似Python、Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用。 groovy的语法跟java完全按类似。
它和java的区别是:
一:java为强类型的语言;Groovy为弱类型,可以自动推断类型;
创建数组的时候Groovy的语法为:def intArray=[2,3,4]
创建MAP的时候Groovy的语法为:def m={}
二:Groovy默认访问修饰符为Public,可以不写访问修饰符
可以直接用def关键字定义,如:
def sayHello(){}
限定访问范围
@PackageScope修饰方法
I. Java程序员为什么学习Groovy
首先Groovy也是运行在java虚拟机上的,二者有语法上的区别但是和java并没有本质上的不同。
Groovy和java是相结合的关系而并不是将java取而代之。
1、Java开发者学习Groovy的成本很低
2、是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言
3、完成同样的事情Groovy可能比Java需要写的代码要少
4、支持单元测试和模拟(对象),可以 简化测试
5、groovy中基本类型也是对象,可以直接调用对象的方法
......
1
2
3
4
5
6
7
8
9
def var="hello "+
"world"+
",groovy!"
def repeat(val){
for(i = 0; i < 5; i++){
println val
}
}
repeat(var)
输出:
hello world,groovy!
hello world,groovy!
hello world,groovy!
hello world,groovy!
hello world,groovy!
最后,为什么要学,这是给那些比较“懒”的java程序员准备的,代码量小啊,而且一些新特性用起来也很方便省心。
J. java和groovy能混编吗
答案是肯定的,java & groovy混编:一种最“势利”的折衷
而groovy,说它是java++也不为过,因为java代码直接就可以被groovy编译, groovy完全兼容java语法, 对一般java开发人员来说,这真是太亲切了