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 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("==================");
}
}
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;
}
添加结果
查询结果、控制台执行结果
第三步:多次修改表数据值,查看执行结果
总语:
目的达成,可见在不重启服务时,多次修改数据,脚本内容都会被动态加载。此处只是简单举例验证,可自行扩展
Java动态脚本Groovy,高级啊!的更多相关文章
- Java动态脚本Groovy读取配置文件
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 核心涉及: @Value:作用是通过注解将常量.配置文件中的值.其他bean的属性值注入到变量中,作为变量的初始值. @Configur ...
- Java动态调用脚本语言Groovy
Java动态调用脚本语言Groovy 2019-05-15 目录 0. pom.xml添加依赖1. 使用GroovyShell计算表达式2. 使用GroovyScriptEngine脚本引擎加载Gro ...
- JAVA嵌入运行Groovy脚本
摘自: http://shift-alt-ctrl.iteye.com/blog/1938238 . 最近设计一个数据统计系统,系统中上百种数据统计维度,而且这些数据统计的指标可能随时会调整.如果基于 ...
- atitit.bsh BeanShell 的动态脚本使用java
atitit.bsh BeanShell 的动态脚本使用java 1.1. BeanShell是一个小巧免费的JAVA源码解释器 ,支持对象式的脚本语言特性,亦可嵌入到JAVA源代码中. 亦可嵌入到J ...
- 教妹学 Java:动态伴侣 Groovy
00.故事的起源 “二哥,听说上一篇<多线程>被 CSDN 创始人蒋涛点赞了?”三妹对她提议的<教妹学 Java>专栏一直很关心. “嗯,有点激动.刚开始还以为是个马甲,没 ...
- Java中运行动态脚本
这里主要总结Java中集成Groovy的应用. Groovy可以与Java完美集成来扩展我们的应用,比如替代Java+jexl实现算式表达式计算或其它功能.在Ofbiz中也集成了Groovy来执行一些 ...
- 180807-Quick-Task 动态脚本支持框架之Groovy脚本加载执行
Quick-Task 动态脚本支持框架之Groovy脚本加载执行 上一篇简答说了如何判断有任务动态添加.删除或更新,归于一点就是监听文件的变化,判断目录下的Groovy文件是否有新增删除和改变,从而判 ...
- java高级---->Java动态代理的原理
Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程 ...
- Javascript高级编程学习笔记(43)—— 动态脚本
动态脚本 大多数情况下,DOM操作都很简洁明了 因为DOM主要就是用来操作页面中的可视节点的 但有些时候我们又希望可以动态的来进行DOM操作 其中的一部分也就是今天我们的内容动态脚本 动态脚本是什么意 ...
随机推荐
- dotNET开发之MVC中Controller返回值类型ActionResult方法总结
1.返回ViewResult视图结果,将视图呈现给网页 2. 返回PartialViewResult部分视图结果,主要用于返回部分视图内容 3. 返回ContentResult用户定义的内容类型 4. ...
- postman调试工具介绍及常用的快捷键收集
关于Postman postman基础功能介绍 使用postman进行接口自动化测试 快捷键大全 简单操作 请求 工具栏 接口 窗口 数据编辑 关于Postman Postman是一款功能强大的网页调 ...
- 【JavaScript定时器小案例】常见的几种定时器实现的案例
[JavaScript定时器小案例]常见的几种定时器实现的案例 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 在日常开发 ...
- Go语言核心36讲(Go语言实战与应用十二)--学习笔记
34 | 并发安全字典sync.Map (上) 我们今天再来讲一个并发安全的高级数据结构:sync.Map.众所周知,Go 语言自带的字典类型map并不是并发安全的. 前导知识:并发安全字典诞生史 换 ...
- 【HTML】WebStorage
WebStorage 2019-11-13 10:46:18 by冲冲 1. 概况 早期浏览器的本地存储使用cookie,当前推荐使用Web Storage. Web Storage的数据以&qu ...
- C#使用Thrift作为RPC框架入门(三)之三层架构
前言 这是我们讲解Thrift框架的第三篇文章,前两篇我们讲了Thrift作为RPC框架的基本用法以及架构的设计.为了我们更好的使用和理解Thrift框架,接下来,我们将来学习一下Thrift框架提供 ...
- 关于CSS的粘性定位sticky失效问题
CSS的粘性定位sticky可以起到吸顶灯的作用,用法如下 <body> <div> <nav style="postion:sticky; top: 0;&q ...
- Qt5加载SVG格式的图片并更颜色
QIcon MainWindow::qiconFromSvg(QString svg_path, QString color) { QPixmap img(svg_path); QPainter qp ...
- CF1418G Three Occurrences
统计满足某些性质的区间个数. 我们考虑移动 \(r\) 指针. 然后考虑把不能选的区间 \(ban\)掉. 具体看下细节吧. #include<iostream> #include< ...
- 洛谷 P7718 -「EZEC-10」Equalization(差分转化+状压 dp)
洛谷题面传送门 一道挺有意思的题,现场切掉还是挺有成就感的. 首先看到区间操作我们可以想到差分转换,将区间操作转化为差分序列上的一个或两个单点操作,具体来说我们设 \(b_i=a_{i+1}-a_i\ ...