Java动态脚本Groovy
作者:南国以南i 时间:2023-12-05 03:25:50
目录
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依赖
<!--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 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 <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
@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脚本数据修改。存于数据库表中,动态加载脚本
@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.总语
目的达成,可见在不重启服务时,多次修改数据,脚本内容都会被动态加载。此处只是简单举例验证,可自行扩展
来源:https://www.cnblogs.com/bgyb/p/15683719.html
标签:Java,动态脚本,Groovy
0
投稿
猜你喜欢
SpringBoot日志框架之Log4j2快速入门与参数详解
2023-11-15 21:17:59
Service Activity的三种交互方式(详解)
2022-03-16 20:55:08
SpringCloud微服务架构升级汇总
2022-05-04 06:09:19
Java 容器类源码详解 Set
2022-03-21 18:08:40
C#图像颜色聚类高效方法实例
2021-09-29 09:14:41
Android使用TransitionDrawable渐变切换多张图片
2023-01-08 16:27:22
App内切换语言详解
2023-04-12 11:21:44
RollViewPager图片轮播效果开源框架使用方法详解
2021-12-06 07:22:59
c#中switch case的用法实例解析
2023-09-20 23:02:51
docker 的java编译环境构建详细介绍
2023-02-10 04:08:30
Java中lombok的@Builder注解的解析与简单使用详解
2022-12-29 06:44:55
SpringBoot整合WebSocket的客户端和服务端的实现代码
2023-03-30 04:19:07
使用cmd根据WSDL网址生成java客户端代码的实现
2022-09-12 11:00:20
C#程序调用cmd.exe执行命令
2022-11-14 04:04:50
mybatis查询返回Map<String,Object>类型的讲解
2022-12-25 02:07:38
java线程之用Thread类创建线程的方法
2023-02-09 18:35:07
C++中String类型的逆序方式
2023-11-19 05:46:52
关于Spring事务隔离、传播属性与@Transactional注解
2021-11-15 04:37:11
C# TSC打印二维码和条形码的实现方法
2021-10-06 14:39:53
Android手机获取IP地址的两种方法
2021-05-28 14:18:51