微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

10、Groovy实现代码热载的机制和原理

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代码输出结果:

在这里插入图片描述

接下来我们来分析一下传入参数和执行脚本代码的源码。

//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] 举报,一经查实,本站将立刻删除。

相关推荐