概述
使用GroovyShell执行groovy脚本
pom.xml中依赖
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.9</version>
</dependency>
evaluate方法执行groovy片段
调用evaluate方法直接执行一段Groovy
public static void testGroovy1() throws CompilationFailedException, IOException {
GroovyShell groovyShell = new GroovyShell();
groovyShell.evaluate("println 'My First Groovy shell.'");
}
原理(源码)解析
步骤:生成一个GroovyCodeSource(脚本及脚本信息)-》GroovyClassLoader 1、
public Object evaluate(String scriptText) throws CompilationFailedException {
return this.evaluate(scriptText, this.generateScriptName(), "/groovy/shell");
}
//scriptText:groovy语句 //this.generateScriptName():生成一个默认的groovy脚本名称 //"/groovy/shell":默认值,用于java的安全管理器 2、
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);
}
3、
public Object evaluate(GroovyCodeSource codeSource) throws CompilationFailedException {
//解析groovy脚本
Script script = this.parse(codeSource);
//运行脚本
return script.run();
}
4、
public Script parse(GroovyCodeSource codeSource) throws CompilationFailedException {
return InvokerHelper.createScript(this.parseClass(codeSource), this.context);
}
5、类加载 GroovyClassLoader
private Class parseClass(GroovyCodeSource codeSource) throws CompilationFailedException {
return this.loader.parseClass(codeSource, false);
}
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);
}
7、
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;
}
7.5创建类采集器
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文件
// 不带参数的groovy方法
def sayHello() {
println 'Hello World.'
// 如果不写return, groovy方法的默认最后一行为 方法的返回值
//return "GroovyShell_1中的sayHello()方法的返回值"
"GroovyShell_1中的sayHello()方法的返回值"
}
// 运行groovy方法
sayHello()
java方法
// 调用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脚本的返回值
}
原理解析
//与上同理,只是将文件中的内容读取成指定类
执行groovy文件(有输入参数)
groovy文件
// 带参数的groovy方法
def sayHello(name) {
println "Hello " + name + "."
// 如果不写return, groovy方法的默认最后一行为 方法的返回值
//return "GroovyShell_1中的sayHello()方法的返回值"
"GroovyShell_1中的sayHello(name)方法的返回值"
}
// 运行groovy方法
sayHello(name)
java方法
// 调用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());
}
原理解析
//输入参数是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
package com.jsq.groovy
class GroovyTest {
static main(args) {
println "hello world"
}
}
编译后的字节码:GroovyTest.class
//
// 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的三种方式使用GroovyShell执行groovy脚本所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复