java里面使用groovy案例+详解

场景: 最近有一个计算商品运费的,如果商品的数量大于快递公司设置的数量 10
那么超出部分也需要计算额外运费,那么这些计算过程代码我能不能不在java里面写呢,用一种可配置化的方式来根据不同的传参计算出运费?

页面传参

[{“key”:“起订量(大单位)”,“isRequired”:true,“isNumber”:true},{“key”:“运费(元)”,“isRequired”:true,“isNumber”:true},{“key”:“续件(大单位)”,“isRequired”:false,“isFixed”:true,“value”:“1”},{“key”:“续件费(元)”,“isRequired”:true},{“key”:“订单金额满
¥ 免运费”,“isRequired”:false,“isFixed”:true,“value”:“800”}]

我需要拿到json里面的value值,然后计算运费

groovy介绍

Groovy是一种动态语言,它运行在Java虚拟机(JVM)上,并且与Java语言兼容。以下是Groovy的一些关键特点和优势:

  1. JVM兼容性:Groovy可以无缝地与Java代码集成,允许开发者在同一个项目中混合使用Groovy和Java代码。这意味着任何Java库都可以在Groovy中使用,反之亦然。

  2. 动态类型:Groovy是一种动态类型语言,这意味着变量的类型在运行时确定,而不是在编译时。这使得Groovy代码更加灵活和简洁。

  3. 简洁的语法:Groovy的语法设计得更加简洁和易于阅读,它提供了许多快捷方式来减少代码量,比如省略类型声明、使用GString(Groovy字符串)等。

  4. 元编程:Groovy支持强大的元编程特性,包括Groovy的闭包(类似于Java 8的Lambda表达式)和动态代理,这使得函数式编程和AOP(面向切面编程)更加容易实现。

  5. 构建工具:Groovy被广泛用于构建工具,特别是Apache Maven和Gradle,后者甚至使用Groovy作为其构建脚本的默认语言。

  6. 测试框架:Groovy与Spock框架(一种基于Groovy的测试框架)紧密集成,使得编写测试用例更加简洁和表达力强。

  7. 并发编程:Groovy提供了对并发编程的支持,包括对Java并发API的封装,以及GPars库,后者提供了对并发和并行编程的高级抽象。

  8. Web开发:Groovy支持多种Web开发框架,如Grails(一个基于Groovy的全栈Web应用框架)和Ratpack(一个用于构建现代HTTP应用的工具包)。

  9. 脚本编写:Groovy的简洁性和强大的标准库使其成为编写脚本的理想选择,尤其是在需要与Java系统集成时。

  10. 社区和生态系统:Groovy有一个活跃的社区和不断增长的生态系统,提供了大量的插件和库来扩展其功能。

Groovy的设计哲学是“让事情更简单”,它旨在提供一种更加简洁和愉快的编程体验,同时保持与Java生态系统的兼容性。这使得Groovy在许多领域,尤其是在企业级应用开发中,成为一种受欢迎的选择。

依赖

<!--    groovy    --><dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.5.11</version><type>pom</type></dependency>

计算结果数据解析

/*** @author sunpeiyang* @date 2024/11/6 13:35*/
@Slf4j
@Component
public class CspGroovyCodeVerification {public Map<String, Object> getFreightAmount(Object value) {Map<String, Object> resultMap = new HashMap<>();// 检查传入的 value 是否为数组if (value != null) {List<Object> resultList = (List<Object>) value;resultMap.put("isFreeFreightAmount", resultList.get(0));resultMap.put("freightAmount", resultList.get(1));}return resultMap;}}

计算结果工具类

@Slf4j
public class CspGroovyUtil {private ScriptEngineManager factory = null;private ScriptEngine engine = null;public CspGroovyUtil() {factory = new ScriptEngineManager();engine = factory.getEngineByName("groovy");engine.getContext().setAttribute("out", new PrintStreamWrapper(), ScriptContext.ENGINE_SCOPE);}public synchronized Object invoke(String script, String name, Object... args) throws ScriptException, NoSuchMethodException {engine.eval(script);return ((Invocable) engine).invokeFunction(name, args);}private static class PrintStreamWrapper {public void println(String x) {log.info("scriptInfoOut={}", x);}}public Object invokeExtra(String script, String name, Object... args) throws ScriptException, NoSuchMethodException {engine.eval(script);return ((Invocable) engine).invokeFunction(name, args);}
}

运费计算

Map<String, Object> resultMap = resultMap = groovyCodeVerification.getFreightAmount(groovyUtil.invoke("def calculationFormula(rule,orderAmount,goodsNumberTotal){  " + cspQuoteRule.getTemplateCalculationFormulaCode() + "  }", "calculationFormula", unitList, freightQuotationSetDetail.getOrderAmount(), freightQuotationSetDetail.getGoodsNumberTotal()));

计算公式

// 满件数(大单位)def fullNum = 0
// 运费()def freight = 0
// 续件(大单位)def continueNum = 0
// 续运费单价(元)def continueFreight = 0
// 免运费的条件金额def freeFreightAmount = 0
// 获取数组的大小def ruleSize = rule.size()
// 运费的结果def resultFreightAmount = 0if(ruleSize > 0){fullNum = rule[0].toInteger()}if(ruleSize > 1){freight = rule[1].toBigDecimal()}if(ruleSize > 2){continueNum = rule[2].toInteger()}if(ruleSize > 3){continueFreight = rule[3].toBigDecimal()}if(ruleSize > 4){freeFreightAmount = rule[4] ? rule[4].toBigDecimal() : BigDecimal.ZERO}if(goodsNumberTotal <= fullNum){resultFreightAmount = freight}else if(goodsNumberTotal > fullNum){// 商品数量大于满件数(大单位),那么 运费 = freight + continueNumBer*continueFreight;def resultGoodsNumberTotal = goodsNumberTotal - fullNumif(resultGoodsNumberTotal > 0){// 续件(大单位)数量计算,不足一进一def continueNumBer = Math.ceil(resultGoodsNumberTotal / continueNum)resultFreightAmount = freight + (continueNumBer * continueFreight)}}
// 如果订单的金额大于门店设置的免运费条件,则免运费def orderAmountResult = orderAmount - freeFreightAmountif(freeFreightAmount > 0 && orderAmountResult >= 0){return [0,resultFreightAmount]}else{return [1,resultFreightAmount]}

简单的案例

在这里插入图片描述

csp_order_freight_expression_debug.groovy

def matchingConditions(rule, orderAmount, goodsNumberTotal) {// 满件数(大单位)def fullNum = 0
// 运费()def freight = 0
// 续件(大单位)def continueNum = 0
// 续运费单价(元)def continueFreight = 0
// 免运费的条件金额def freeFreightAmount = 0
// 获取数组的大小def ruleSize = rule.size()
// 运费的结果def resultFreightAmount = 0if(ruleSize > 0){fullNum = rule[0].toInteger()}if(ruleSize > 1){freight = rule[1].toBigDecimal()}if(ruleSize > 2){continueNum = rule[2].toInteger()}if(ruleSize > 3){continueFreight = rule[3].toBigDecimal()}if(ruleSize > 4){freeFreightAmount = rule[4] ? rule[4].toBigDecimal() : BigDecimal.ZERO}if(goodsNumberTotal <= fullNum){resultFreightAmount = freight}else if(goodsNumberTotal > fullNum){// 商品数量大于满件数(大单位),那么 运费 = freight + continueNumBer*continueFreight;def resultGoodsNumberTotal = goodsNumberTotal - fullNumif(resultGoodsNumberTotal > 0){// 续件(大单位)数量计算,不足一进一def continueNumBer = Math.ceil(resultGoodsNumberTotal / continueNum)resultFreightAmount = freight + (continueNumBer * continueFreight)}}
// 如果订单的金额大于门店设置的免运费条件,则免运费def orderAmountResult = orderAmount - freeFreightAmountif(freeFreightAmount > 0 && orderAmountResult >= 0){return [0,resultFreightAmount]}else{return [1,resultFreightAmount]}
}// 销售单商品运费的计算公式
List<String> unitList = ['2', '200', '1', '7', '30']BigDecimal orderAmount = 30BigDecimal goodsNumberTotal = 3matchingConditions(unitList, orderAmount, goodsNumberTotal);

🤔 Groovy和Java的主要区别是什么?

Groovy和Java都是运行在Java虚拟机(JVM)上的编程语言,但它们之间存在一些关键的区别:

  1. 静态类型与动态类型

    • Java:是一种静态类型语言,变量的类型在编译时确定,必须显式声明变量的类型。
    • Groovy:是一种动态类型语言,变量的类型在运行时确定,不需要显式声明变量的类型。
  2. 语法简洁性

    • Java:语法较为严格和冗长,需要编写更多的样板代码。
    • Groovy:提供了更简洁的语法,支持多种编程范式,包括面向对象、函数式和命令式编程,减少了代码量。
  3. 元编程能力

    • Java:虽然Java 8引入了Lambda表达式和方法引用,但元编程能力有限。
    • Groovy:提供了强大的元编程能力,包括闭包、Groovy对象(GString)、动态方法调用和属性访问等。
  4. 集成和兼容性

    • Java:虽然可以调用Groovy代码,但需要一些额外的配置。
    • Groovy:可以无缝集成Java代码,不需要任何额外的配置,Groovy代码可以作为Java代码的直接替代。
  5. 构建工具和脚本

    • Java:通常使用Ant或Maven等构建工具,这些工具使用XML配置文件。
    • Groovy:Groovy被广泛用于构建工具,如Gradle,它使用Groovy作为构建脚本语言,提供了更灵活和强大的构建配置。
  6. 测试框架

    • Java:通常使用JUnit等测试框架。
    • Groovy:除了JUnit,还支持Spock框架,这是一个基于Groovy的测试框架,提供了更简洁和强大的测试DSL。
  7. 并发编程

    • Java:提供了丰富的并发API,如java.util.concurrent包。
    • Groovy:除了Java的并发API,还提供了GPars库,这是一个Groovy的并发编程库,提供了更高级的并发和并行编程抽象。
  8. Web框架

    • Java:有Spring、JavaServer Faces (JSF)、Struts等Web框架。
    • Groovy:有Grails(一个全栈Web应用框架)和Ratpack(一个用于构建现代HTTP应用的工具包)。
  9. 社区和生态系统

    • Java:拥有庞大的社区和成熟的生态系统。
    • Groovy:社区相对较小,但生态系统在不断增长,特别是在企业级应用和自动化脚本领域。

总的来说,Groovy提供了一种更加灵活和简洁的方式来编写JVM上的代码,而Java则提供了更严格的类型检查和广泛的社区支持。选择哪种语言取决于具体的项目需求和团队偏好。

🤓 Groovy是否适合大型企业级应用开发?

Groovy作为一种运行在JVM上的动态语言,非常适合大型企业级应用开发,主要原因如下:

  1. 与Java的无缝集成:Groovy可以直接使用Java的类库和API,同时Java代码也可以轻松调用Groovy脚本,这使得Groovy在Java生态系统中具有很高的兼容性。

  2. 动态语言特性:Groovy支持动态类型、元编程和闭包等特性,使得代码编写更加灵活和简洁。它提供了更简洁的语法和更少的样板代码,提高了开发效率。

  3. 丰富的库和扩展:Groovy提供了许多库和扩展,涵盖了数据库访问、JSON处理、并发编程等领域,这些库使得Groovy在企业级应用开发中更加强大和灵活。

  4. 性能表现:尽管Groovy是一种动态语言,但其性能表现非常出色。在JVM的支持下,Groovy代码的运行速度接近原生Java代码。

  5. 领域特定语言(DSL)开发:Groovy的DSL支持使得开发者可以为特定领域创建定制化的语言,如配置文件解析、SQL查询生成等,进一步提高开发效率。

  6. Web开发:Groovy可以与各种Web框架(如Grails)结合使用,实现快速、高效的Web开发。

  7. 并发编程支持:Groovy提供了对并发编程的支持,包括Groovyx.gpars.actor库中的Actor模型,使得编写多线程应用程序变得更加简单和安全。

  8. AST转换:Groovy的AST转换允许在编译时修改程序的抽象语法树,这可以用来实现自定义注解、创建DSL或者改变程序的行为。

  9. 企业级应用案例:Groovy被广泛用于构建工具,如Gradle,以及在Jira等项目管理工具中,显示了其在企业级应用中的适用性和重要性。

  10. 安全性和稳定性:Groovy提供了一些被动安全手段,比如采用线程池隔离,对脚本执行进行有效的实时监控、统计和封装,或者是手动强杀执行脚本的线程,增强了企业级应用的安全性和稳定性。

综上所述,Groovy以其与Java的高度兼容性、动态语言特性、丰富的库支持、性能优势以及在企业级应用中的广泛使用,非常适合大型企业级应用开发。

🔍 Groovy在构建企业级工具时有哪些优势?

Groovy在构建企业级工具时的优势主要体现在以下几个方面:

  1. 与Java的无缝集成:Groovy可以直接使用Java的类库和API,同时Java代码也可以轻松调用Groovy脚本,这使得Groovy在Java生态系统中具有很高的兼容性。

  2. 动态语言特性:Groovy支持动态类型、元编程和闭包等特性,使得代码编写更加灵活和简洁,提供了更简洁的语法和更少的样板代码,提高了开发效率。

  3. 丰富的生态系统:Groovy有着庞大且活跃的社区,众多的库和框架提供了丰富的解决方案,简化了企业级应用开发的工作。例如,Grails和Spock等框架都有着很高的社区支持,使得开发人员能够更加高效地构建应用和编写测试。

  4. 简化构建流程:Groovy与Gradle构建工具的紧密结合,使得开发人员可以通过编写自定义插件来自动化常见的构建任务和流程,减少手动配置和干预。

  5. 并行编译和增量编译:利用Gradle 3.1的并行编译和增量编译功能,可以显著减少构建时间,提高构建性能。

  6. 领域特定语言(DSL)开发:Groovy的DSL支持使得开发者可以为特定领域创建定制化的语言,如配置文件解析、SQL查询生成等,进一步提高开发效率。

  7. 性能优越:尽管Groovy是一种动态语言,但其性能表现非常出色。在JVM的支持下,Groovy代码的运行速度接近原生Java代码。

  8. 脚本编写:Groovy非常适合用于编写各种脚本,如构建脚本、自动化测试脚本等。其简洁的语法和动态性使得脚本编写更加快速、高效。

  9. 跨平台兼容性:Groovy Eclipse兼容Eclipse 3.2及其以上版本,因此可以在多种操作系统上运行,为企业提供了更大的灵活性。

  10. 丰富的插件生态系统:Groovy Eclipse作为Eclipse的一部分,可以访问庞大的插件生态系统,这些插件能够扩展其功能,满足特定的开发需求。

  11. 社区支持:Groovy和Eclipse社区活跃,为开发者提供了丰富的资源和支持,包括文档、教程和论坛等,有助于解决开发过程中遇到的问题。

这些优势使得Groovy成为企业级工具开发中的一个有力选择,特别是在需要灵活性、简洁性和强大社区支持的场景下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/11633.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

iframe页面嵌套把子页面的modal显示在父页面层级

使用iframe父页面嵌套子页面时&#xff0c;如果子页面有modal&#xff0c;默认modal的包裹范围是在子页面的body上&#xff0c;子页面有多大&#xff0c;modal的包裹就有多大&#xff0c;并且不能fixed&#xff0c;会随着鼠标滚动。 处理方法&#xff1a;将modal的body挂载在页…

18.头文件的用法注意事项

//2.cpp中编写多个方法&#xff0c;方法多了后没法一个个声明&#xff0c;就需要使用头文件 int daguai() {return 1; } int paoshang() {return 1; } int guaji() {return 1; } int jiaxue() {return 1; }右键头文件 新建项 新建头文件 在头文件中声明2.cpp中的方法 #pr…

充电宝哪个牌子好用?2024年充电宝十大品牌排行榜推荐!

充电宝哪个牌子好用&#xff1f;2024年充电宝十大品牌排行榜推荐&#xff01;如今&#xff0c;外出时手机电量耗尽是许多人都会遇到的问题&#xff0c;尤其是在关键时刻&#xff0c;电量不足更是令人焦虑不已。此时&#xff0c;一款性能可靠且耐用的移动电源便成了我们的救命稻…

Python爬虫精准获取京东(JD)商品SKU信息

在数字化时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是对于电商行业来说&#xff0c;精准获取商品信息成为了市场分析、价格比较、库存管理等环节的基石。本文将通过Python爬虫技术&#xff0c;详细解析如何精准获取京东(JD)商品的SKU信息&#xff0c;包括商品详情、价…

漏洞利用exp[banner]

源码 import requestsbanner """________________________________________________/ \\| _________________________________________ || |\033[1;39m _,. \0…

MYSQL视图

由于我们上讲复习了前面的所有知识点&#xff0c;所以今天不再去复习之前的知识了&#xff0c;我们直接开始正题。 1.什么是视图&#xff1f; 视图是⼀个虚拟的表&#xff0c;它是基于⼀个或多个基本表或其他视图的查询结果集。视图本⾝不存储数 据&#xff0c;⽽是通过执⾏查…

【软件设计师中级】2024.11.09软考备考

备考时候的一些笔记&#xff0c;可能会有不对或者个人主观的知识点 文章目录 前言一、计算机内数据的表示1.1 原反补移码1.2 浮点数1.3 校验码1.3.1奇偶校验1.3.2 CRC冗余校验码(理解特点即可)1.3.3 海明校验码 二、 计算机系统组成2.1 冯诺依曼结构2.2 Flynn分类法2.3 指令系统…

springboot生成二维码和条形码

目录 springboot生成二维码和条形码引入依赖生成二维码&#xff0c;在controller层生成条形码controller springboot生成二维码和条形码 引入依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version&…

RTSP播放器EasyPlayer.js无插件直播流媒体音视频播放器使用http与https的区别

在当今数字化时代&#xff0c;视频播放体验的重要性日益凸显&#xff0c;而EasyPlayer.js无插件H5播放器作为一款现代Web环境下的播放器&#xff0c;其对HTTP和HTTPS的支持成为了许多用户关注的焦点。本文将探讨EasyPlayer.js播放器在使用HTTP与HTTPS时的区别。 1、从安全性角度…

组态软件基础知识

一、组态软件基础知识 1、概述 &#xff08;1&#xff09;、组态软件概念与产生背景 “组态”的概念是伴随着集散型控制系统&#xff08;Distributed Control System简称DCS&#xff09;的出现才开始被广大的生产过程自动化技术人员所熟知的。在工业控制技术的不断发…

国标GB28181公网直播EasyGBS国标GB28181视频平台与海康GB28181对接需要做哪些测试?

在当今的视频监控系统中&#xff0c;国标GB28181协议已成为视频监控设备互联互通的标准。特别是在公网直播的应用场景中&#xff0c;国标GB28181公网直播EasyGBS国标GB28181视频平台与海康威视设备的对接显得尤为重要。为了确保对接的顺利进行&#xff0c;需要进行一系列详尽的…

SpringBoot使用TraceId日志链路追踪

项目场景&#xff1a; 有时候一个业务调用链场景&#xff0c;很长&#xff0c;调了各种各样的方法&#xff0c;看日志的时候&#xff0c;各个接口的日志穿插&#xff0c;确实让人头大。为了解决这个痛点&#xff0c;就使用了TraceId&#xff0c;根据TraceId关键字进入服务器查询…

【QML】QML图表(ChartView)改变坐标轴(ValueAxis)标题(titleText)的文字颜色

1. 需求 改变titleText的颜色&#xff0c;将下图mV的颜色改为红色 2.代码 关键代码&#xff1a;titleText: "<font colorred>mV</font>" //坐标轴 mv ValueAxis{id: _mAxisMvmin: 0max: 20tickCount: 6labelsFont.pixelSize: 15labelFormat: %.1ft…

mysql诡异查询

运营同事让查一个数量&#xff0c;结果这两种情况查的居然不一致。 带时分秒查询的是另一个数&#xff0c;没有时分秒是上面的&#xff0c;少了100多条数据&#xff0c;为什么&#xff0c;有路过的大神可以指点一二。

丹摩征文活动|快速上手 CogVideoX-2b:智谱清影 6 秒视频生成部署教程

文章目录 一、生成视频效果 二、CogVideoX 技术新起点三、CogVideoX 上手部署3.1 创建丹摩实例3.2 配置环境和依赖3.3 模型与配置文件3.4 运行3.5 问题与处理方法 四、CogVideoX-2b 用创新点燃未来 一、生成视频效果 A street artist, clad in a worn-out denim jacket and a c…

仓库管理系统的实施流程超全解析!

现在我们都能很清楚地知道&#xff0c;在企业管理中仓库管理系统&#xff08;WMS&#xff09;扮演着非常重要的角色。而且随着电子商务的迅猛发展和供应链管理的复杂化&#xff0c;企业对仓库管理的要求越来越高。那么&#xff0c;如何有效地实施一个仓库管理系统&#xff0c;成…

【K8S问题系列 | 10】在K8S集群怎么查看各个pod占用的资源大小?【已解决】

要查看 Kubernetes 集群中各个 Pod 占用的资源大小&#xff08;包括 CPU 和内存&#xff09;&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用 kubectl top 命令 kubectl top 命令可以快速查看当前 Pod 的 CPU 和内存使用情况。需要确保已安装并配置了 Metrics Server。…

YOLO即插即用模块---MEGANet

MEGANet: Multi-Scale Edge-Guided Attention Network for Weak Boundary Polyp Segmentation 论文地址&#xff1a; 解决问题&#xff1a; 解决方案细节&#xff1a; 解决方案用于目标检测&#xff1a; 即插即用代码&#xff1a; 论文地址&#xff1a; https://arxiv.org…

测试求职个人简历案例参考

当涉及到测试求职个人简历时&#xff0c;关键是突出你在测试领域的技能和经验。以下是一个例子&#xff0c;它包含了简历的常见部分&#xff0c;以突出测试方面的专业知识和个人成就。 基本信息 姓名&#xff1a;XXX 电话&#xff1a;123456789 邮箱&#xff1a;jianli100chui.…

Chromium Mojo(IPC)进程通信演示 c++(3)

122版本自带的mojom通信例子channel-associated-interface 仅供学习参考&#xff1a; codelabs\mojo_examples\03-channel-associated-interface-freezing 其余定义参考上一篇文章&#xff1a; Chromium Mojo(IPC)进程通信演示 c&#xff08;2&#xff09;-CSDN博客​​​​…