Java动态脚本Groovy,高级啊!

Java动态脚本Groovy,高级啊!

前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i

简介:

Groovy是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。

Groovy特性:

可将java代码在Groovy脚本动态编码、代码被修改达到不重启服务的目的(类似于热部署)

核心涉及:

ClassLoader:就是类的装载器,它使JVM可以动态的载入Java类,JVM并不需要知道从什么地方(本地文件网络等)载入Java类,这些都由ClassLoader完成。

GroovyClassLoader:动态地加载一个脚本并执行它的行为。GroovyClassLoader是一个定制的类装载器,负责解释加载Java类中用到的Groovy类。

Java与Groovy转换

第一步:引入Groovy依赖

    <!--Groovy脚本依赖-->        <dependency>            <groupId>org.codehaus.groovy</groupId>            <artifactId>groovy</artifactId>            <version>2.5.14</version>        </dependency>

第二步:创建interface接口声明方法

public interface CallAnalysis {     default void load() {    }}

第三步:在resources目录下创建.groovy文件

package groovyimport com.example.groovy.testgroovy.task.CallAnalysisimport groovy.util.logging.Slf4j@Slf4jclass CallAnalysisImpl implements CallAnalysis{    @Override    void load() {        log.info("我被Groovy脚本加载...")    }}

第四步:创建Groovy脚本装载类,动态解析脚本为Class

package com.example.groovy.testgroovy.task;import groovy.lang.GroovyClassLoader;public class GroovyUtils {    private final static ClassLoader classLoader = GroovyUtils.class.getClassLoader();//获取当前类装载器    //ClassLoader:就是类的装载器,它使JVM可以动态的载入Java类,JVM并不需要知道从什么地方(本地文件、网络等)载入Java类,这些都由ClassLoader完成。    public final static GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader);    //GroovyClassLoader:负责在运行时编译groovy源代码为Class的工作,从而使Groovy实现了将groovy源代码动态加载为Class的功能    /**     * .     * 获取实例化对象     * @param script groovy脚本内容     * @param <T>     * @return     * @throws IllegalAccessException     * @throws InstantiationException     */    public static <T> T instanceTaskGroovyScript(String script) throws IllegalAccessException, InstantiationException {        Class taskClz = groovyClassLoader.parseClass(script);        T instance = (T) taskClz.newInstance();        return instance;    }}

第五步:读取脚本内容,执行脚本

package com.example.groovy.testgroovy.task;import lombok.extern.slf4j.Slf4j;import org.apache.commons.io.FileUtils;import org.springframework.stereotype.Component;import java.io.File;import java.io.IOException;@Slf4j@Componentpublic class CallAnalysisGroovyTask {    /**     * .     * 读取脚本内容     *     * @return     */    public static String getGroovy() {        String context = "";        try {            String path = "E:\\IDEAFile\\testgroovy\\src\\main\\resources\\groovy\\CallAnalysisImpl.groovy";            context = FileUtils.readFileToString(new File(path));//将脚本内容转为字符串        } catch (IOException e) {            log.error("file is not found[{}]", e);        }        return context;    }    /**     * .     * 执行groovy脚本     *     * @param script     */    public static void execGroovy(String script) {        try {            CallAnalysis objClass = GroovyUtils.instanceTaskGroovyScript(script);//获取实例对象            objClass.load();//调用脚本方法        } catch (Exception t) {            log.error("execGroovy file {} error", script);        }    }    /**     * .     * main方法     * @param args     */    public static void main(String[] args) {        System.out.println("==================");        CallAnalysisGroovyTask task = new CallAnalysisGroovyTask();        String script = task.getGroovy();//获取脚本        execGroovy(script);//实例化脚本,执行方法        System.out.println("==================");    }}

Groovy特性验证

利用Groovy脚本特性,不重启服务,实时修改数据

第一步:将之前Groovy脚本数据修改。存于数据库表中,动态加载脚本

@Slf4jclass CallAnalysisImpl implements CallAnalysis {    private int anInt = 10;    private int bnInt = 10;    @Override    void load() {        log.info("当前类:[{}]", this.getClass().getName())        log.info("我被Groovy脚本加载...")        log.info("计算结果:[{}]", (anInt + bnInt))    }}

第二步:数据库表中:添加、查询Groovy脚本,动态加载执行

 /**     * .     * 读取脚本,进行入库操作     *     * @return     */    @GetMapping("/saveScript")    public String saveScript() {        String scriptStr = callAnalysisGroovyTask.getGroovy();        Script script = new Script();//实体类对象        script.setScript(scriptStr);//脚本内容        script.setRuleId("1");//规则id        script.setScriptName("演示一");//脚本名称        service.save(script);        return "添加成功";    }    /**     * .     * 从数据库表中,动态获取脚本     *     * @param ruleId 规则id     * @return 脚本内容     */    @GetMapping("/groovy")    public String groovy(final String ruleId) {        Script scr = scriptService.findScriptByRuleId(ruleId);//根据规则id查询        String scriptStr = scr.getScript();        callAnalysisGroovyTask.execGroovy(scriptStr);        return scriptStr;    }

添加结果

查询结果、控制台执行结果

第三步:多次修改表数据值,查看执行结果

总语:

目的达成,可见在不重启服务时,多次修改数据,脚本内容都会被动态加载。此处只是简单举例验证,可自行扩展


__EOF__

  • 本文作者: 南国以南i
  • 本文链接: https://www.cnblogs.com/bgyb/p/15683719.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
    相关文章
    返回顶部