10、Groovy实现代码热载的机制和原理
我们知道,Groovy在很大一部分的用途是在java工程里面穿插使用的,本文的主题是Groovy实现代码热载,,其他大背景是java实现主干代码,,groovy实现易变动的逻辑代码. 先来看下java是如何调用的groovy脚本的。
Groovy代码热载例子
import groovy.lang.Binding;
import groovy.lang.groovyshell;
public class GroovyTest {
public static void main(String[] args) {
// *) groovy 代码
String script = "println 'hello'; 'name = ' + name;";
// *) 传入参数
Binding binding = new Binding();
binding.setvariable("name", "lilei");
// *) 执行脚本代码
groovyshell shell = new groovyshell(binding);
Object res = shell.evaluate(script);
System.out.println(res);
}
}
//groovy.lang.binding
//一个收集参数的map属性
private Map variables;
public Binding() {
}
//构造函数
public Binding(Map variables) {
this.variables = variables;
}
public Binding(String[] args) {
this();
this.setvariable("args", args);
}
//余下的是对参数数据map的一些操作,就不列出来了
所以Binging里面其实就是用一个map存储其传来的参数而已,我们再来看groovyshell类,对于其中的函数evaluate, 我们追踪进去, 会有不少的新认识。
public Object evaluate(GroovyCodeSource codeSource) throws CompilationFailedException {
Script script = this.parse(codeSource);
return script.run();
}
public Script parse(GroovyCodeSource codeSource) throws CompilationFailedException {
return InvokerHelper.createScript(this.parseClass(codeSource), this.context);
}
其大致的思路, 为Groovy脚本代码包装生成class, 然后产生该类实例对象, 在具体执行其包装的逻辑代码。而在parse方法的parseClass源码如下所示:
public Class parseClass(String text) throws CompilationFailedException {
return this.parseClass(text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy");
}
对于groovy脚本, 它默认会生成名字为script + System.currentTimeMillis() + Math.abs(text.hashCode())的class类, 也就是说传入脚本, 它都会生成一个新类, 就算同一段groovy脚本代码, 每调用一次, 都会生成一个新类。
总结
对于Groovy脚本,先用Binding传入参数到map数组里面,再根据Binding创建groovyshell对象, 然后为Groovy脚本代码包装生成class, 然后产生该类实例对象, 在具体执行其包装的逻辑代码。而在parse方法的parseClass源码如下所示。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。