我是靠谱客的博主 等待凉面,这篇文章主要介绍Java中使用Groovy的三种方式使用GroovyShell执行groovy脚本,现在分享给大家,希望可以做个参考。

使用GroovyShell执行groovy脚本

pom.xml中依赖

复制代码
1
2
3
4
5
<dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>3.0.9</version> </dependency>

evaluate方法执行groovy片段

复制代码
1
调用evaluate方法直接执行一段Groovy
复制代码
1
2
3
4
public static void testGroovy1() throws CompilationFailedException, IOException { GroovyShell groovyShell = new GroovyShell(); groovyShell.evaluate("println 'My First Groovy shell.'"); }

原理(源码)解析

复制代码
1
2
步骤:生成一个GroovyCodeSource(脚本及脚本信息)-》GroovyClassLoader 1、
复制代码
1
2
3
public Object evaluate(String scriptText) throws CompilationFailedException { return this.evaluate(scriptText, this.generateScriptName(), "/groovy/shell"); }
复制代码
1
2
3
4
//scriptText:groovy语句 //this.generateScriptName():生成一个默认的groovy脚本名称 //"/groovy/shell":默认值,用于java的安全管理器 2、
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
public Object evaluate(String scriptText, String fileName, String codeBase) throws CompilationFailedException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new GroovyCodeSourcePermission(codeBase)); } //安全管理 GroovyCodeSource gcs = (GroovyCodeSource)AccessController.doPrivileged(() -> { return new GroovyCodeSource(scriptText, fileName, codeBase); }); //构建GroovyCodeSource return this.evaluate(gcs); }
复制代码
1
3、
复制代码
1
2
3
4
5
6
public Object evaluate(GroovyCodeSource codeSource) throws CompilationFailedException { //解析groovy脚本 Script script = this.parse(codeSource); //运行脚本 return script.run(); }
复制代码
1
4、
复制代码
1
2
3
public Script parse(GroovyCodeSource codeSource) throws CompilationFailedException { return InvokerHelper.createScript(this.parseClass(codeSource), this.context); }
复制代码
1
5、类加载 GroovyClassLoader
复制代码
1
2
3
private Class parseClass(GroovyCodeSource codeSource) throws CompilationFailedException { return this.loader.parseClass(codeSource, false); }
复制代码
1
6、是否使用缓存
复制代码
1
2
3
4
5
6
public Class parseClass(GroovyCodeSource codeSource, boolean shouldCacheSource) throws CompilationFailedException { String cacheKey = this.genSourceCacheKey(codeSource); return (Class)this.sourceCache.getAndPut(cacheKey, (key) -> { return this.doParseClass(codeSource); }, shouldCacheSource); }
复制代码
1
7、
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private Class doParseClass(GroovyCodeSource codeSource) { validate(codeSource); //创建编译单元 CompilationUnit unit = this.createCompilationUnit(this.config, codeSource.getCodeSource()); if (this.recompile != null && this.recompile || this.recompile == null && this.config.getRecompileGroovySource()) { unit.addFirstPhaseOperation(GroovyClassLoader.TimestampAdder.INSTANCE, CompilePhase.CLASS_GENERATION.getPhaseNumber()); } //资源单元 SourceUnit su; ... // GroovyClassLoader.ClassCollector collector = this.createCollector(unit, su); unit.setClassgenCallback(collector); ... //编译 unit.compile(goalPhase); Class answer = collector.generatedClass; String mainClass = su.getAST().getMainClassName(); Iterator var9 = collector.getLoadedClasses().iterator(); while(var9.hasNext()) { Object o = var9.next(); Class clazz = (Class)o; String clazzName = clazz.getName(); this.definePackageInternal(clazzName); this.setClassCacheEntry(clazz); if (clazzName.equals(mainClass)) { answer = clazz; } } return answer; }
复制代码
1
7.5创建类采集器
复制代码
1
2
3
4
5
6
protected GroovyClassLoader.ClassCollector createCollector(CompilationUnit unit, SourceUnit su) { GroovyClassLoader.InnerLoader loader = (GroovyClassLoader.InnerLoader)AccessController.doPrivileged(() -> { return new GroovyClassLoader.InnerLoader(this); }); return new GroovyClassLoader.ClassCollector(loader, unit, su); }

执行groovy文件(无输入参数)

groovy文件

复制代码
1
2
3
4
5
6
7
8
9
// 不带参数的groovy方法 def sayHello() { println 'Hello World.' // 如果不写return, groovy方法的默认最后一行为 方法的返回值 //return "GroovyShell_1中的sayHello()方法的返回值" "GroovyShell_1中的sayHello()方法的返回值" } // 运行groovy方法 sayHello()

java方法

复制代码
1
2
3
4
5
6
// 调用GroovyShell_1_1文件 public static void testGroovy2() throws CompilationFailedException, IOException { GroovyShell groovyShell = new GroovyShell(); Object result = groovyShell.evaluate(new File("src/main/java/com/juxinli/groovy/GroovyShell_1_1.groovy")); logger.info(result.toString());//result 为groovy脚本的返回值 }

原理解析

复制代码
1
//与上同理,只是将文件中的内容读取成指定类

执行groovy文件(有输入参数)

groovy文件

复制代码
1
2
3
4
5
6
7
8
9
// 带参数的groovy方法 def sayHello(name) { println "Hello " + name + "." // 如果不写return, groovy方法的默认最后一行为 方法的返回值 //return "GroovyShell_1中的sayHello()方法的返回值" "GroovyShell_1中的sayHello(name)方法的返回值" } // 运行groovy方法 sayHello(name)

java方法

复制代码
1
2
3
4
5
6
7
8
9
// 调用GroovyShell_1_2 public static void testGroovy3() throws CompilationFailedException, IOException { // 调用带参数的groovy shell时,使用bind绑定数据 Binding binding = new Binding(); binding.setProperty("name", "Juxinli"); //用Binding类绑定参数 GroovyShell groovyShell = new GroovyShell(binding);//执行groovy文件时,传入Binging类 Object result = groovyShell.evaluate(new File("src/main/java/com/juxinli/groovy/GroovyShell_1_2.groovy")); logger.info(result.toString()); }

原理解析

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//输入参数是GroovyShell中的属性context的属性 public class GroovyShell extends GroovyObjectSupport { private final Binding context; public GroovyShell(Binding binding) { this((ClassLoader)null, (Binding)binding); } ... } //执行脚本 groovyShell.evaluate(groovy文件) //this.context为输入参数 public Script parse(GroovyCodeSource codeSource) throws CompilationFailedException { return InvokerHelper.createScript(this.parseClass(codeSource), this.context); } //将Binding的输入参数与main方法中的输入参数绑定 public static Script createScript(Class scriptClass, Binding context) { ... Object args = this.getProperty("args"); object.invokeMethod("main", argsToPass); ... }

groovy文件编译为字节码(class文件)

IDEA中可以直接运行groovy文件,将.groovy文件可以编译为.class文件

如:GroovyTest.groovy

复制代码
1
2
3
4
5
6
7
package com.jsq.groovy class GroovyTest { static main(args) { println "hello world" } }

编译后的字节码:GroovyTest.class

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.jsq.groovy; import groovy.lang.GroovyObject; import groovy.lang.MetaClass; import groovy.transform.Generated; import groovy.transform.Internal; import java.beans.Transient; import org.codehaus.groovy.runtime.callsite.CallSite; public class GroovyTest implements GroovyObject { @Generated public GroovyTest() { CallSite[] var1 = $getCallSiteArray(); super(); MetaClass var2 = this.$getStaticMetaClass(); this.metaClass = var2; } public static void main(String... args) { CallSite[] var1 = $getCallSiteArray(); var1[0].callStatic(GroovyTest.class, "hello world"); } @Generated @Internal @Transient public MetaClass getMetaClass() { MetaClass var10000 = this.metaClass; if (var10000 != null) { return var10000; } else { this.metaClass = this.$getStaticMetaClass(); return this.metaClass; } } @Generated @Internal public void setMetaClass(MetaClass var1) { this.metaClass = var1; } }

最后

以上就是等待凉面最近收集整理的关于Java中使用Groovy的三种方式使用GroovyShell执行groovy脚本的全部内容,更多相关Java中使用Groovy内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部