iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java 内嵌Groovy动态脚本操作
  • 367
分享到

java 内嵌Groovy动态脚本操作

2024-04-02 19:04:59 367人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

固定的策略有时候还是无法满足千变万化的需求变动,一方面需要支持特定的用户需求,另一方面又得尽可能的复用代码,避免重复开发,这就需要将这部分的特殊的需求剥离出来,采用动态配置规则的方式

固定的策略有时候还是无法满足千变万化的需求变动,一方面需要支持特定的用户需求,另一方面又得尽可能的复用代码,避免重复开发,这就需要将这部分的特殊的需求剥离出来,采用动态配置规则的方式来实现。

java有三种方式调用groovy脚本

但是真正在实际的服务器环境中,嵌入groovy脚本往往需要满足下面的条件:

  1. 可以直接调用groovy脚本中的方法
  2. 能传递对象到groovy方法中,不仅仅是字符串
  3. 提供脚本缓存机制,不用每次调用脚本的时候,都到磁盘读取
  4. 修改groovy后能实时生效

第一种:通过GroovyShell来执行groovy脚本

第二种:通过GroovyClassLoader动态加载Groovy Class

第三种:使用GroovyScriptEngine脚本引擎加载Groovy脚本

本实例使用第二种动态加载脚本

Groovy的基本语法

由于Groovy脚本语言能够直接编译成java的class字节码,并且还支持java的类库,运行在java虚拟机上,其能够很好的跟java进行交互,因此利用groovy的动态特性,来实现需求频繁变动的且变态的需求,并且不需要重启服务器。

以下是代码测试control类


package com.WEBTest.dynamicGroovy.controller; 
import groovy.lang.GroovyObject; 
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.Http.httpservletRequest; 
import org.apache.log4j.Logger;
import org.codehaus.groovy.control.CompilationFailedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.base.common.GroovyUtils;
import com.webTest.dynamicGroovy.bean.GroovyBean;
import com.webTest.dynamicGroovy.groovyInterface.CallBackGroovyInvoke;
import com.webTest.dynamicGroovy.service.CallBackGroovy;
 
@Controller
@RequestMapping("/groovyTest")
public class GroovyControl {	
	private Logger logger = Logger.getLogger(GroovyControl.class);		
	@Autowired
	private CallBackGroovy callBackGroovy;		
	@ResponseBody
	@RequestMapping(value="/groovy1.do",method={RequestMethod.GET,RequestMethod.POST})
	public  Object testGroovy(HttpServletRequest request) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		logger.info("测试动态脚本语言Groovy Begin。。。");
		String name="崔春驰";
		String realPath = request.getSession().getServletContext().getRealPath("groovyFile");
		String groovyNameString = "\\hello.groovy";
		String path = realPath+groovyNameString;
		File file = new File(path);
		
		//获得class,并存放入堆缓存
		Class<?> groovyClass = GroovyUtils.CLASS_LOADER.parseClass("myFirstGroovy",file,true);
		//获取groovyObject的实例
		GroovyObject  groovyObject = (GroovyObject) groovyClass.newInstance();
		//反射执行方法,得到返回信息   传多个参数 new Object[]{bean,request,new HashMap<>()}
		Object invokeResult = groovyObject.invokeMethod("sayHello", name);
		if(invokeResult != null){
			System.out.println(invokeResult.toString());
		}
		//清楚缓存中的map  是为了grrovy脚本变化,清楚堆中缓存,重新类加载
		logger.info("测试动态脚本语言Groovy End。。。");
		return invokeResult;
	}
	
	@ResponseBody
	@RequestMapping(value="/groovy2.do",method={RequestMethod.GET,RequestMethod.POST})
	public  Object testGroovy2(HttpServletRequest request) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		logger.info("测试动态脚本语言Groovy2 Begin。。。");
		String realPath = request.getSession().getServletContext().getRealPath("groovyFile");
		String groovyNameString = "\\testGroovyBean.groovy";
		String path = realPath+groovyNameString;
		File file = new File(path);
		
		GroovyBean bean = new GroovyBean();
		bean.setNameString("王小二");bean.setAge(12);
		Map<String, Object> map = new HashMap<>();
		map.put("address", "江苏南京");
		
		//获得class,并存放入堆缓存
		Class<?> groovyClass = GroovyUtils.CLASS_LOADER.parseClass("mySecondGroovy",file,true);
		//获取groovyObject的实例
		CallBackGroovyInvoke  groovyObject = (CallBackGroovyInvoke) groovyClass.newInstance();
		//反射执行方法,得到返回信息
		Object doCallBackVal = groovyObject.doCallBack(bean, request, map);
		
		if(doCallBackVal instanceof GroovyBean){
			GroovyBean bean2  = (GroovyBean) doCallBackVal;
			System.out.println("用户信息---》"+bean2.getNameString() + ":"+bean2.getAge()+"岁");
		}
		System.out.println("统一groovy接口返回数据————————》"+doCallBackVal);
		//清楚缓存中的map  是为了grrovy脚本变化,清楚堆中缓存,重新类加载
		logger.info("测试动态脚本语言Groovy2 End。。。");
		return doCallBackVal;
	}
	
	@ResponseBody
	@RequestMapping(value="/clearGroovyCache.do",method={RequestMethod.GET,RequestMethod.POST})
	public void clearCache(){
		//根据指定key来清楚
		GroovyUtils.CLASS_LOADER.clearCache("myFirstGroovy");
		//清楚所有
		GroovyUtils.CLASS_LOADER.clearCache();
	}
}

以下为groovyUtils。


public class GroovyUtils { 
 public static GroovyClassLoaderCommon CLASS_LOADER = null; 
 static {
  CompilerConfiguration configuration = CompilerConfiguration.DEFAULT;
  configuration.setSourceEncoding("UTF-8");
  CLASS_LOADER = new GroovyClassLoaderCommon(GroovyControl.class.getClassLoader(), configuration);
 } 
}

以下为GroovyClassLoaderCommon,继承了GroovyClassLoader,主要是重写了,parseClass方法,并且添加了可以清除sourceCache的map缓存,以及可以remove指定的class信息,用于更改groovy文件后,可以及时响应。


package com.webTest.dynamicGroovy; 
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource; 
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; 
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration; 
public final class GroovyClassLoaderCommon extends GroovyClassLoader{
	
	//这一步可以放入分布式缓存中,如Redis中,统一来管理,防止多次对groovy的变动,可以根据缓存开关来及时的更新到JVM中
	private static final Map<String, Object> CACHEMAP_MAP = new ConcurrentHashMap<>();
	
	public GroovyClassLoaderCommon() {
		super();
	}
	
	public GroovyClassLoaderCommon(ClassLoader loader, CompilerConfiguration config){
		super(loader, config);
	}
	
	
	public Class<?> parseClass(String key,File file,
			boolean shouldCacheSource) throws CompilationFailedException, FileNotFoundException {
		GroovyCodeSource codeSource = new GroovyCodeSource(file);
		codeSource.setCachable(shouldCacheSource);
		if(shouldCacheSource) CACHEMAP_MAP.put(key, codeSource.getName());
		return super.parseClass(codeSource);
	}
	
	
	public void clearCache(){
		synchronized (this) {
			sourceCache.clear();
		}
	}
	
	public void clearCache(String key){
		Object value = CACHEMAP_MAP.get(key);
		synchronized (this) {
			if(sourceCache.containsKey(value)) sourceCache.remove(value);
			if(CACHEMAP_MAP.containsKey(key)) CACHEMAP_MAP.remove(key);
		}
	} 
}
 
import java.util.Date; 
def sayHello(name){
	println name+"向你说 “你好!!”";
	def date = new Date();
	return "success sayHello()+test  groovy" +date;
} 
<!--可以直接调用 -->
sayHello('asda');

import com.webTest.dynamicGroovy.groovyInterface.CallBackGroovyInvoke;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import com.webTest.dynamicGroovy.bean.GroovyBean;
import org.slf4j.Logger
import org.slf4j.LoggerFactory
 
class testGroovyBean implements CallBackGroovyInvoke{
	public static final Logger LOGGER = LoggerFactory.getLogger(testGroovyBean.class);	
	def doCallBack(GroovyBean bean ,HttpServletRequest request, Map<String, Object> map){
		LOGGER.info("groovy 中记录日志。。。。");
		println "测试接口groovy 获取用户信息:"+bean.getNameString() + " ;年龄:"+bean.getAge();
		println "设置用户信息:";
		bean.setNameString("蛮王");bean.setAge(200);
		def map1 = ['name':'王大锤','sex':'男'];
		map = map+map1+['weight':'160'];
		def str =  otherMethod();
		LOGGER.info(str);
//		return map
		return bean;
	}
	
	def otherMethod(){
		println "在不重启应用的情况下,调用内部其他方法";
		return "我进入了,另一个方法!";
	}
}

以上就是测试的这些,至于其框架使用的map容器作为缓存,因jvmGC不会对该容器进行清除,所以为防止内存溢出,可采用自定义的缓存策略,如基于容量、基于时间、基于java对象引用、基于缓存算法(LRU最近最少使用、LFU最不常用、FIFO先进先出),可不用groovy中的容器,及设置缓存设为false,则不放入容器,然后将其生成的实例可放入分布式缓存中redis即可。

仅为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: java 内嵌Groovy动态脚本操作

本文链接: https://www.lsjlt.com/news/130035.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java 内嵌Groovy动态脚本操作
    固定的策略有时候还是无法满足千变万化的需求变动,一方面需要支持特定的用户需求,另一方面又得尽可能的复用代码,避免重复开发,这就需要将这部分的特殊的需求剥离出来,采用动态配置规则的方式...
    99+
    2024-04-02
  • Java动态脚本Groovy
    目录1.Groovy特性 2.核心涉及 3.Java与Groovy转换 第一步:引入Groovy依赖 第二步:创建interface接口声明方法 第三步:在resources目录下创...
    99+
    2024-04-02
  • Java动态脚本Groovy获取Bean技巧
    目录一、使用BeanFactoryPostProcessor注入Bean: 第一步:创建实现SpringUtils 接口工具(组件)来获取spring bean 第二步:创建Groo...
    99+
    2024-04-02
  • Java动态脚本Groovy的特性是什么
    这篇文章主要为大家展示了“Java动态脚本Groovy的特性是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java动态脚本Groovy的特性是什么”这篇文章吧。1.Groovy特性可将ja...
    99+
    2023-06-22
  • Java动态脚本Groovy获取Bean技巧是什么
    本篇内容介绍了“Java动态脚本Groovy获取Bean技巧是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在Groovy中不能使用@A...
    99+
    2023-06-22
  • SpringBoot整合Groovy脚本实现动态编程详解
    目录Groovy简介应用场景集成与使用第一步、与SpringBoot集成1、pom.xml文件如下:第二步、写出Groovy版本的“Hello World”1...
    99+
    2024-04-02
  • Python代码如何通过动态脚本语言进行操作
    这篇文章将为大家详细讲解有关Python代码如何通过动态脚本语言进行操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。我们在计算机语言的应用中一般情况下我们都可跳过Build这些Projec...
    99+
    2023-06-17
  • SpringBoot之内嵌tomcat版本升级操作示例
    目录Spring Boot之如何升级内嵌tomcat版本1. 背景修复方案如下:2. 过程2.1 升级单模块项目的tomcat版本2.2 升级包含多个模块的项目3. 项目有打包子模块...
    99+
    2024-04-02
  • Windows编写jar启动脚本和关闭脚本的操作方法
    目录前言启动脚本编写关闭脚本restart.bat 重启脚本前言 假设项目打包后,项目结构为: 此时如果需要再windows环境中进行项目的启动或关闭,需要频繁的手敲命令,很不方便...
    99+
    2022-12-29
    Windows编写jar启动脚本 Windows jar关闭脚本 Windows jar脚本
  • Windows自动执行python脚本操作步骤
    目录运行Python脚本:.bat文件python脚本bat运行经验定时在Windows中触发.bat文件上一篇自动在Windows中运行Python脚本并定时触发功能实现传送门链接...
    99+
    2024-04-02
  • Java详解ScriptEngine接口动态执行JS脚本
    目录简介Eval(String script)描述实例代码Put() and Get()描述实例代码CompiledScript描述实例代码Bindings描述实例代码大多的方法描述...
    99+
    2022-11-13
    Java ScriptEngine Java 动态执行JavaScript脚本
  • java脚本怎么设置多个动态变量
    在Java脚本中,可以使用多个变量来存储和操作不同的值。下面是几种设置多个动态变量的方法:1. 使用单独的变量来存储每个值:```j...
    99+
    2023-09-15
    java
  • Java应用开发中如何用脚本自动化日常操作
    今天就跟大家聊聊有关Java应用开发中如何用脚本自动化日常操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在日常开发时,我经常会遇到如下问题:查看某个用户的某些操作信息(不需要界面...
    99+
    2023-06-17
  • 在Java中如何使用groovy语言作为动态规则表达式
    小编给大家分享一下在Java中如何使用groovy语言作为动态规则表达式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!由于在工作流设计中需要为条件分支设定条件表达...
    99+
    2023-06-17
  • PHP Linux脚本操作实例:实现自动化部署
    近年来,随着软件行业的快速发展,部署工作在开发流程中变得愈发重要。为了提高效率,许多开发团队都开始采用自动化部署来简化繁琐的部署过程。在这其中,PHP语言在Linux环境下的脚本操作成为了一种常见的实现方式。本文将介绍如何使用PHP脚本在L...
    99+
    2023-10-21
    Linux PHP 自动化部署
  • python selenium 模拟浏览器自动操作抢购脚本
    每逢秒杀,都在遗憾网速和手速慢没能抢购到商品吧。 手写一个脚本,让程序帮你抢,抢到的概率会大大提升。 废话不多说,直接上代码。 本实例以华为官网抢购手机为例 """(1) 安装 chromedriver a. 去官网 (http://chr...
    99+
    2023-09-13
    python selenium 开发语言
  • k8s自动化安装脚本(二进制)的操作步骤
    目录介绍部署结构操作步骤环境准备部署包下载总结介绍 通过ansible脚本+shell实现自动化部署k8s基础集群(v1.25.0) 部署结构 1. 通过二进制部署包镜像安装k8s...
    99+
    2024-04-02
  • Java动态模拟操作系统进程调度算法
    目录实验目的设备与环境实验内容实验结果及分析部分代码展示 实验目的 通过对进程调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。 设备与环境...
    99+
    2024-04-02
  • 如何在Java中使用Shell脚本操作数组和文件?
    Java是一种非常流行的编程语言,常用于开发Web应用程序和移动应用程序。在Java中,我们可以使用Shell脚本来操作数组和文件,这使得开发者可以更加轻松地管理数据和文件。本文将介绍如何在Java中使用Shell脚本操作数组和文件。 一、...
    99+
    2023-10-31
    shell 数组 文件
  • 如何通过PHP脚本在Linux服务器上自动化操作
    在Linux服务器上,使用PHP脚本可以实现各种自动化操作,如备份数据库、定时任务、文件管理等。接下来将介绍如何使用PHP脚本来实现这些自动化操作,并提供具体的代码示例。备份数据库数据库的备份是服务器管理的一项重要任务,通过PHP脚本可以实...
    99+
    2023-10-21
    linux服务器 PHP脚本 自动化操作
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作