Groovy动态加载Java代码的使用方法和工具类

java脚本引擎Groovy实战 ​互联网时代随着业务的飞速发展,不仅产品迭代、更新的速度越来越快,个性化需求也是越来越多。如何快速的满足各种业务的个性化需求是我们要重点思考的问题。我们开发的系统如何才能做到热部署就能适应各种规则变化呢?实现业务和规则的解耦。 好了,Java的ScriptEngine脚本引擎给了我们一个选择,它支持代码动态执行,代码修改后不需要重启JVM进程,就可以使用解析或编译方式执行,非常方便,在一些动态业务规则、热更新、热修复等场景中会非常方便。 阅读详情

一、使用场景

你是否遇到过:线上环境复杂,发包申请复杂,代码稳健性差,或者某段代码需要视线上运行情况而更改的!又或者类似解析脚本经常变动,通配符优化等等!更新、打包、发布申请、然后再发布…
Groovy则提供了相关的动态加载能力来解决这些问题,并且简单易懂,非常好用!

二、Groovy优缺点

缺点

  1. 使用Groovy会增加一定的代码复杂度,因为你原本只用写业务代码就行,但现在你不但要写业务代码,还要增加Groovy的代码。
  2. Groovy有两种方式,一种是使用他自己的Groovy语言来进行处理,这要求学习Groovy。另一种则是使用Groovy提供的java版本工具包,使用Java语言处理,这个方法没有新的学习成本,但是要求写的非常详细,例如引入一个对象,则需要把对应的import也写出来,否则就会报错。
  3. 考虑动态代码的异常处理。

优点

  1. 动态加载代码,避免重复劳动,可以放在文件里,或者配置到界面上,真的很方便!!!
  2. 有Java版本的Groovy工具,可以直接使用Java代码,不用学习新的语言。
  3. 首次加载新的代码会慢一些,但是后面和正常代码速度差不多(个人测试感觉)。

三、工具类

网上有很多Java的Groovy的工具的使用方法讲的比较清楚,我项目中因为很多地方会使用到,所以就顺手写了个工具类,有需要的可以复制使用。

首先引入POM:

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>3.0.9</version>
        </dependency>

然后复制粘贴:

import groovy.lang.GroovyClassLoader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GroovyHandler {

    private Class<?> clazz;
    private Object instance;
    private Method method;
    private Constructor<?> constructor;

	//加载String类型的代码
    public GroovyHandler(String javasShell) {
        this.clazz = new GroovyClassLoader().parseClass(javasShell);
    }
    //加载文件类型的代码
    public GroovyHandler(File file) {
        try {
            this.clazz = new GroovyClassLoader().parseClass(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	//设置构造函数(如果代码里带有Class)
    public void setConstructor(Class<?>... parameterTypes) {
        try {
            this.constructor = this.clazz.getConstructor(parameterTypes);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
	//设置构造函数的参数并生成实例对象
    public void setInstance(Object... constructorValue) {
        try {
            if(this.constructor == null){
                this.instance = this.clazz.newInstance();
            }else {
                this.instance = this.constructor.newInstance(constructorValue);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
	//设置要调用方法(如果有参数,带上参数类型)
    public void setMethod(String methodName, Class<?>... parameterTypes) {
        try {
            this.method = this.clazz.getDeclaredMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
	//调用方法(如果有参数,带上参数值)
    public Object doInvoke(Object... args) {
        try {
            return this.method.invoke(this.instance, args);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }


}

四、使用示例

//示例代码:
//1.如果需要直接调用某个方法,没有构造函数:
//脚本例如下面:
//    public String getBuilder(String name){
//        return name + ":builder";
//    }
public static void main(String[] args) {
        String scirpt = "public String getBuilder(String name){\n" +
                "        return name + \":builder\";\n" +
                "    }";
        //加载字符串
        GroovyHandler groovyHandler = new GroovyHandler(scirpt);
        //加载文件
        //GroovyHandler groovyHandler = new GroovyHandler(file);
        //直接生成类的实例对象
        groovyHandler.setInstance();
        //设置需要调用的方法并传参数的类型(如果没有参数则不写)
        groovyHandler.setMethod("getBuilder",String.class);
        //反射调用方法并传参(如果没有参数则不写,传回的值可以进行强转)
        String result = (String) groovyHandler.doInvoke("zhangsan");
        System.out.println(result);
    }
//输出结果:zhangsn:builder

//2.有构造函数
//脚本代码例如下面的:
//public class TestGroovy {
//    private String age;
//
//    public TestGroovy(String age) {
//        this.age = age;
//    }
//
//    public String getNewStr(String name) {
//        return name + ":" + age;
//    }
//}
 public static void main(String[] args) {
        String script = "public class TestGroovy {\n" +
                "    private String age;\n" +
                "\n" +
                "    public TestGroovy(String age) {\n" +
                "        this.age = age;\n" +
                "    }\n" +
                "\n" +
                "    public String getNewStr(String name) {\n" +
                "        return name + \":\" + age;\n" +
                "    }\n" +
                "}";

        //加载String
        GroovyHandler groovyHandler = new GroovyHandler(script);
        //加载文件
        //GroovyHandler groovyHandler = new GroovyHandler(file);
        if (groovyHandler != null) {
            //如果代码脚本里面有构造函数需要调用,先调用第一句,参数填写构造的参数类型!
            groovyHandler.setConstructor(String.class);
            //然后传入上面构造函数需要的参数,groovy会自动生成实例对象
            groovyHandler.setInstance("18");
            //设置需要调用的方法并传参数的类型(如果没有参数则不写)
            groovyHandler.setMethod("getNewStr",String.class);
            //反射调用方法并传参(如果没有参数则不写,传回的值可以进行强转)
            String result = (String)groovyHandler.doInvoke("zhangsan");
            System.out.println(result);
        }
    }
//输出结果:zhangsan:18

需要注意的是Groovy加载的代码里,必须要包含对应对象的引用,传对象参数时,则需要将对象的Import地址添加上,否则Groovy找不到对应的类,会报Null错误!!!

总结:Groovy可以动态加载代码,在某些应用场景下还是很方便的!但是需要代码需要写的完善一些,并且做好异常处理。如果有问题可以问我,或者有错误指点请弹我,祝永无Bug!

Java 热更新 Groovy 实践及踩坑指南 此时需要监控中心介入,提前部署好异动规则,当异常发生时,监控中心发出告警通知到对应的规则创建人员,从而尽快查明原因,挽回资损。在初期方案上线时,压测后显示,首次加载脚本性能较慢,后续脚本执行速度非常快,猜测可能是 Groovy 内部在首次脚在脚本时还做了其他的校验(本人还没跟进这块,如果有读者感兴趣,可以断点详细看下链路耗时在哪里)风控的规则引擎非常适合用 groovy 来实现,对抗黑产,策略人员每天都都会产出拦截规则,如果每次都需要发版,可能发完观测完后,该薅的羊毛都被黑产薅没了。 阅读详情

相关推荐

从零搭建开发脚手架 Spring Boot 集成Groovy实现动态加载业务规则

try {// 每隔多少秒,扫描目录下的groovy文件。

2401_89317568的博客 874

java代码中使用Groovy的三种方式详解

java代码中使用Groovy的三种方式详解

qq_36305027的博客 1万+

掌握Java动态代码执行技术:Groovy实战指南

动态代码执行是指在运行时构建和执行代码的能力。与传统的静态编译执行不同,动态执行允许在程序运行过程中修改和执行新的代码片段,甚至可以执行预先未知的代码。// 示例代码,展示Java中使用eval方法动态执行字符串形式的代码try {");通过上述示例,可以看出动态代码执行可以在运行时即时构建并执行代码,这极大地提升了程序的灵活性。Groovy是一种强大的动态语言,运行在Java平台上,它与Java有着天然的亲缘关系。

weixin_35815766的博客 842

秒懂Groovy【仅限于Java开发者】

Groovy学习

良木 4898

groovy和Java相互调用1

Groovy 调用 Java 类groovy 调用 Java class 十分方便,只需要在类前导入该 Java 类,在 Groovy 代码中就可以无缝使用该

深入解析6T SRAM的读写机制与性能优化

本文深入解析了6T SRAM的基本结构与核心工作原理,详细阐述了其读写操作的具体时序与机制。文章重点探讨了在先进工艺下面临的读写稳定性、写入能力等性能挑战,并系统介绍了写入辅助与读取辅助等关键优化技术,旨在提升SRAM的可靠性与整体性能。

weixin_29205061的博客 1225

groovy代码动态加载运行实战

class Calculator { //groovy语法 def discount(a,b){ def c = a * b } //java语法 int add(int a, int b){ return a + b; } //java语法 String addStr(Map map){

somilong的博客 8444

webview腾讯x5内核离线安装

离线集成腾讯TBS浏览器服务,彻底解决官方下载限流问题,永久免费

观千剑而后识器,操千曲而后晓声。 7908

java脚本引擎Groovy动态执行

1.2.3.4.5.

DN金猿的博客 545

学习笔记——神经科学的数学基础

m%3D2X_%7Bi%7DiNy%3DAxW%3DABx_%7Bj%7Dy_%7Bi%7Dy%3DWxt=N7T8卷积神经网络(CNN)详细介绍及其原理详解_IronmanJay的博客-优快云博客https://blog.youkuaiyun.com/IronmanJay/article/details/128689946?

zxyopenstar的博客 1374

PCB线路板的制作工艺流程分享!2021-08-21

Pcb板制作工艺流程:开料-钻孔-沉铜-压膜-曝光-显影-电铜-电锡-退膜-蚀刻-退锡-光学检测-印阻焊油-阻焊曝光、显影-字符-表面处理-成型-电测-终检-抽测-包装。具体如下:1、开料(CUT) 将原始的覆铜板切割成可以用在生产线上制作的板子过程2、钻孔 使PCB板层间产生通孔,以达到连通层间的目的。 3、沉铜 经过钻孔后的线路板在沉铜缸内会发生氧化还原反应,形成铜层对孔进行孔金属化,使原来绝缘的基材表面沉积上铜,达到层间电性相通。 4、压膜 压膜后的PCB板上面压了一层蓝色的干膜, 干膜是一个载体

jdbpcb88的博客 3246

groovy 三种运用

1、groovyShell 脚本语言运用,支持表达式及脚本文件: def run(foo) {        println 'Hello World!'        x = 123        foo * 10 } run foo   public class TestGroovyShell {  /**   * @param args   */  public st

zj7758的专栏 1万+

ITK-snap医学图像标注方法(超级详细)——保姆级

医学3D图像标注方法,非常详细,保姆级

jialiyk的博客 3万+

在JAVA中运行Groovy

Groovy被设计为轻量级和容易嵌入到Java应用程序系统。 1、Groovy脚本样例 def run(foo) {        println 'Hello World!'        x = 123        foo * 10 }   run foo l         Groovy脚本样例包含run()函数,并在最后调用run(),返回结果 l     ...

summer85的博客 240

Autosar MCAL-S32K324 Fee配置-基于EB

Autosar MCAL S32K324 Fee配置详解

赞的博客 1544

深入探讨:StoreKit 2的交易处理与收据验证

iOS应用开发中,StoreKit 2带来收据处理和交易验证的新变化。本文通过实例分析,对比传统StoreKit与StoreKit 2的差异,指出直接访问sandboxReceipt文件可能引发错误。解决方案是使用Transaction对象和SKReceiptRefreshRequest,详细介绍了如何初始化ReceiptLoader、处理交易更新及验证收据的完整流程,帮助开发者适应新框架,确保购买流程安全可靠。

m0_74337424的博客 357

java 加载groove,教你Java如何动态调用Groove代码

Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate和其它标准Java框架之上,从而为大家带来一套能实现超高生产力的一站式框架。1 目的动态执行任务或者扩展功能,需要java动态执行groovy代码2 项目依赖org.codehaus.groovygroovy-all2.5.2pomcom.alibabafastjson1.2.4...

weixin_39735012的博客 1051

TI硬件笔试面试题型解析上

摘要: 本专栏聚焦大厂硬件笔试面试题解析,当前第14期以德州仪器(TI)为例,涵盖模拟电路与数字电路核心考点。模拟电路部分涉及最大功率传递定理、运放设计(虚短/虚断)、共模抑制比(CMRR)及高频PCB信号完整性;数字电路包括CMOS与TTL对比、建立/保持时间、竞争冒险消除、D触发器分频及“线与”逻辑实现。文章强调通过例题掌握解题方法与知识点,助力读者应对硬件工程岗位的笔试与面试挑战,附常见考点总结与实用建议。全文注重理论与实践结合,提供典型题型解析与设计思路。(150字)

启芯硬件的博客 950

java脚本引擎groovy,groovy 三种运用 | 学步园

1、groovyShell 脚本语言运用,支持表达式及脚本文件:def run(foo) {println 'Hello World!'x = 123foo * 10}run foopublic class TestGroovyShell {/*** @param args*/public static void main(String[] args) {try {Binding binding ...

weixin_42396058的博客 547

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

java如何动态的执行groovy字符串

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

qq_63815371的博客 926

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Groovy全攻略--嵌入篇

Groovy被设计得非常轻量级,很容易迁入到任何Java应用系统。你可以使用BSF将Groovy脚本嵌入任何Java代码中.但是Groovy提供了一个轻量级的紧密集成.下面是3种主要方法:1.使用Shell调试脚本或表达式在Groovy中你可以使用GroovyShell对Groovy脚本和表达式进行调试.GroovyShell允许你通过Binding对象传入或传出变量. // 从Java代码...

summer85的博客 371

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

在Java中运行Groovy代码(原创)

Groovy被设计为轻量级和容易嵌入到Java应用程序系统。1、Groovy脚本样例def run(foo) {       println Hello World!       x = 123       foo * 10} run fool         Groovy脚本样例包含run()函数,并在最后调用run(),返回结果l         调用run()时传递的参数

3483

10、Groovy实现代码热载的机制和原理

10、Groovy实现代码热载的机制和原理 我们知道,Groovy在很大一部分的用途是在java工程里面穿插使用的,本文的主题是Groovy实现代码热载,,其他大背景是java实现主干代码,,groovy实现易变动的逻辑代码. 先来看下java是如何调用的groovy脚本的。 Groovy代码热载例子 import groovy.lang.Binding; import groovy.lang.GroovyShell; public class GroovyTest { public sta

m0_51121824的博客 801

java groovy 动态计算_spring + groovy 实现动态代码注入执行

昨天线上的代码调用一个远程的服务无缘无故不成功,又没加那么多日志,不好定位问题,好想在线上执行一下代码,打印点log看看 于是想着怎么动态执行点java代码,忽然想起以前玩过的groovy,于是搞起来大概思路是这样,写一个控制器,接收一段代码,动态执行,然后返回执行结果,切记,做好权限控制,免得杯具没想到实现起来异常简单1、gradle.build加入groovy依赖compile "org.co...

weixin_32064437的博客 739

在 Java 应用程序中加一些 Groovy 进来

如果您一直在阅读这个系列,那么您应该已经看到有各种各样使用 Groovy 的有趣方式,Groovy 的主要优势之一就是它的生产力。Groovy 代码通常要比 Java 代码更容易编写,而且编写起来也更快,这使得它有足够的资格成为开发工作包中的一个附件。在另一方面,正如我在这个系列中反复强调的那样,Groovy 并不是 —— 而且也不打算成为 —— Java 语言的替代。所以,这里存在的问题是,能否...

chenyulancn的专栏 285

Java动态调用Groove代码(1)-GroovyClassLoader

1 目的 动态执行任务或者扩展功能,需要java动态执行groovy代码 2 项目依赖 &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.codehaus.groovy&lt;/groupId&gt; &lt;artifactId&gt;groovy-all&lt;/artifactId&gt; ...

chy2z的专栏 1万+
上一篇: 多值判断、包含的简写EqualUtil工具类
下一篇: H5界面预览或下载文件(Minio或本地文件)
黄焖大排骨
博客等级 码龄8年 52粉丝 19原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值