阅读 594

Java动态脚本Groovy

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

目录
  • 1.Groovy特性

  • 2.核心涉及

  • 3.Java与Groovy转换

    • 第一步:引入Groovy依赖

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

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

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

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

  • 4.Groovy特性验证

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

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

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

  • 5.总语

    1.Groovy特性

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

    2.核心涉及

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

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

    3.Java与Groovy转换

    第一步:引入Groovy依赖

    1
    2
    3
    4
    5
    6
    <!--Groovy脚本依赖-->
         <dependency>
             <groupId>org.codehaus.groovy</groupId>
             <artifactId>groovy</artifactId>
             <version>2.5.14</version>
         </dependency>

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

    1
    2
    3
    4
    public interface CallAnalysis {
         default void load() {
        }
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package groovy
     
    import com.example.groovy.testgroovy.task.CallAnalysis
    import groovy.util.logging.Slf4j
     
    @Slf4j
    class CallAnalysisImpl implements CallAnalysis{
     
        @Override
        void load() {
            log.info("我被Groovy脚本加载...")
        }
    }

    第四步:创建Groovy脚本装载类,动态解析脚本为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
    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;
        }
    }

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


    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    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
    @Component
    public 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("==================");
        }
    }

    4.Groovy特性验证

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Slf4j
    class 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脚本,动态加载执行

    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
    /**
        * .
        * 读取脚本,进行入库操作
        *
        * @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;
       }

    添加结果:

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

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

    5.总语

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

    到此这篇关于Java动态脚本Groovy的文章就介绍到这了

    原文链接:https://www.cnblogs.com/bgyb/p/15683719.html

    伪原创工具 SEO网站优化  https://www.237it.com/ 


    文章分类
    百科问答
    版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
    相关推荐