Java动态脚本Groovy

网友投稿 323 2022-11-15

Java动态脚本Groovy

目录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依赖

org.codehaus.groovy

groovy

2.5.14

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

public interface CallAnalysis {

default void load() {

}

}

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

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

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

* @return

* @throws IllegalAccessException

* @throws InstantiationException

*/

public static 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

@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

http:// */

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脚本数据修改。存于数据库表中,动态加载脚本

@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脚本,动态加载执行

/**

* .

* 读取脚本,进行入库操作

*

* @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.总语

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于Blackfin DSP的TFT LCD液晶接口设计
下一篇:WebSocket和Socket的区别_WebSocket和http的区别_WebScoket的长连接和http的长连接的区别_spring的单例bean是线程安全的吗_http请求头请求行请求体
相关文章

 发表评论

暂时没有评论,来抢沙发吧~