Groovy DSL从入门到项目实战(一)

news2024/11/17 0:06:38

Groovy是一门很灵活的Java扩展语言,支持弱类型、闭包、函数式编程等脚本语言的高级特性。因为小卷所在公司的船申报系统需要重构,对原先java硬编码的各种表单数据校验、后台业务校验使用规则脚本的形式进行剥离出来。而市面上像Jboss Drools这样的规则引擎又感觉太重了,所以选择更轻量级也更容易在java体系中整合的groovy,为此,开始新一轮的groovy dsl学习之旅。

因为groovy dsl的脚本形式有非常好的可读性,且只要有jvm虚拟机环境就可以独立或者嵌入到当前java模块中运行,这就是gradle作为项目构建工具非常受欢迎的原因,因为它提供了高可读、高可维护性、高灵活度的dsl软件构建脚本。

如果你跟小卷一样做全栈开发,体验过前端从jsts的严谨,那你一定也想体验下后端从javagroovy的松散洒脱。咱们一起开始groovy学习之旅吧。

文章目录

    • 学习参考
    • 工程搭建
    • 语法特性初体验
      • 类型由运行时决定
      • list和map操作
      • 闭包 - 声明与执行分离
      • 操作符重载
      • 正则
      • 标记语言构建器

学习参考

万变不离其宗的官方参考文档

csdn优质创作者猿泰山 博客:

  • 深入解析Groovy:灵活性与生产力的完美融合
  • Groovy与Spring Boot整合入门教程

PACKT出版社出版的:Groovy for Domain-specific Languages - 第二版英文版 (Dearle, Fergal)

说明

这本英文实战书是小卷学习的主要参考,里面涉及到groovy dsl语言特性的更多实战。在后续的博文分享中也会体现出来。

工程搭建

在这里插入图片描述

在这里插入图片描述

语法特性初体验

类型由运行时决定

def myVar = 'hello'
println myVar.class

myVar = 123.4
println myVar.class

Java里的类型是编译时就确定了,而groovy中则在运行时才被确定,这里def也可以用String声明,这样在赋值其他类型时存在一个隐式转换。

练一练

将上面代码加到com/juan/groovy/Main.groovymain方法中,先用def声明,再改成String,看输出。后续练习若无说明,默认也在Main.groovymain方法中编写。

list和map操作

// list定义与访问
def students = ['小张', '小李', '小王']
println students
println students[1]

// map定义与访问
def lili = [name: '莉莉', age: 22]
println lili
println lili.name
println lili['age']

定义和访问方式跟js类似,注意这里对象字面量的定义形式用[ ... ]而不是{ ... }

闭包 - 声明与执行分离

// 闭包可以当作一个有入参和返回值的函数
def min = { num1, num2 -> Math.min(num1, num2) }
// 通过call来调用
def result = min.call(2, 3)
println result

// 直接用函数变量名调用
result = min(2, 3)
println result

// 调用时括号可以省略
result = min 2, 3
println result

现在咱们姑且先把闭包当作一个函数来使用,注意,闭包中定义的内容是用{ ... }进行关闭和隔离的。再来看一个实现打印的小栗子:

// 实现一个打印的闭包
def myPrint = { a -> print a }
myPrint ('hello\n')

def myPrint2 = { a, b -> print a; print b }
myPrint2 ('hello', 'world\n')

groovy语法的魅力,化繁为简,语法可以精简到如下程度:

def myPrint = { print it } // 一个参数时可以使用隐式变量it
myPrint 'hello\n' // 括号可以省略

def myPrint2 = { a, b -> print a print b } // 这里的分号也可以省略
myPrint2 'hello', 'world\n' // 括号可以省略

什么时候不能省略分号

一般的执行语句都可以省略;,当然也有一些特殊情况,比如:

def a = 1; def b = 2 // 两个def的声明语句中间的;不能省略
print a print b // 可省略;

再来看个求最小的小练习来巩固下闭包函数的用法:

// 定义求最小值的闭包
// 箭头函数体内的语句无需分号,最后一个语句为返回值
def min = { list ->
    def min = list[0]
    list.each { n -> if (n < min) min = n }
    min
}
def list = [ 5, 2, 3, 1, 4, 6]
println min(list) // 这里min的括号调用不可省略

println( min list ) // 这种形式也是可以的

操作符重载

groovy仿照C++实现语言基本特性的操作符重载,可以扩展类中相应的方法来实现操作符的重载,比如plus()方法,不同的类型提供的不同的plus()方法的重载来实现+操作符,操作数的类型不同,实现也不一样,看例子:

def str = 'hello '
str = str.plus('groovy')
println str

def d = 123.4
d = d.plus(12) // 如果是'12'呢,尝试改下
println d

正则

比如实现一个字符串多个连续空格替换为一个:

def str = '      aa  bbb    cc  '
// =~ 操作符表示对目标字符串应用正则模式,执行结果为一个匹配器,这里是匹配多个连续空格
def matcher = str =~ ' +'
def result = matcher.replaceAll(' ')
println "|$result|"
// 字符串模板中的表达式写法,注意,外面要用双引号包裹
println "|${result + '!!!'}|"

标记语言构建器

需要引入依赖:

implementation 'org.apache.groovy:groovy-xml:4.0.14'

这个groovy-xml充分实现了dsl给标记语言的声明所带来的可读性和可维护性,比写原生标记语言要强太多

def writer = new StringWriter()
def builder = new MarkupBuilder(writer)
builder.course {
    author {
        name '小卷'
    }
    title '跟着小卷学groovy'
    price 0 // 完全免费
}

println writer

这里通过groovy-xml扩展模块的标记语言构建器,可以很轻松的对groovy的对象声明的简洁语法构建出xml格式的数据,以满足远程服务调用所需的格式,非常简单!得到的输出结果:

<course>
  <author>
    <name>小卷</name>
  </author>
  <title>跟着小卷学groovy</title>
  <price>0</price>
</course>

关于类型导入

一般的常用类型、内置类型,在groovy代码中都不需要导入;而对于第三方的模块中的类型,需要导入其类型。

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

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

相关文章

docker-compose安装sentry

官方文档 https://develop.sentry.dev/self-hosted/ 一、前提 服务器配置至少4C16G&#xff0c;否则起不来 二、安装docker https://blog.csdn.net/weixin_45112997/article/details/134532660 三、安装docker-compose docker-compose版本有要求&#xff0c;必须大于2.…

ISO7841标准数字隔离器在现代电子系统中的作用

在快速发展的电子领域&#xff0c;隔离元件在确保各种系统的安全性、可靠性和性能方面发挥着关键作用。其中&#xff0c;光耦合器是提供电气隔离同时允许电路不同部分之间进行信号传输的关键设备。ISO7841数字隔离器尤其体现了现代电子设计所需的先进功能和多功能性。 ISO7841数…

刷题刷题刷题

89. 格雷编码 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<int> grayCode(int n) {vector<int> res;res.push_back(0);int head 1;for (int i 0; i < n; i) {for (int j res.size() - 1; j > 0; j--) {res.push_back(head r…

电脑录屏怎么录?强烈推荐这5款高清录屏软件

现在电脑录屏作为数字化生活的一项实用技能&#xff0c;正逐渐走进越来越多人的视野&#xff0c;无论是想要录制游戏直播的高光时刻&#xff0c;还是制作教学视频分享知识&#xff0c;亦或是记录会议内容以备不时之需&#xff0c;电脑录屏都能轻松满足我们的需求。 今天就给大家…

Leetcode 876.141.142.143 环形链表 C++实现

Leetcode 876. 链表的中间结点 问题&#xff1a;给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点。 、 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

【MySQL进阶之路】oracle 9i的经典测试雇员信息表案例——多表查询

目录 引言 笛卡尔积 自连接 子查询 单行子查询 多行子查询 多列子查询 在from子句中使用子查询 合并查询 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 在数据库的实际开发中&#xff0c;多表查询是一项非常基础且重要的技能。它允许你将来自不同表的数据结合…

【git bash编码错误解决方案】启动conda环境时报错,其他terminal却正常

&#x1f50e;嘿&#xff0c;这里是慰慰&#x1f469;&#x1f3fb;‍&#x1f393;&#xff0c;会发各种类型的文章&#xff0c;智能专业&#xff0c;从事前端&#x1f43e; &#x1f389;如果有帮助的话&#xff0c;就点个赞叭&#xff0c;让我开心一下&#xff01;&#x1f…

Java中的IO流-最全最基础的IO流概述和简介

IO流简介 IO是什么 Java中的IO流是用于处理数据输入和输出的核心机制。通过应用IO流可以使Java程序能够与外部世界&#xff08;如磁盘文件、网络、硬件设备等&#xff09;进行数据交互。IO流的全称为输入/输出流&#xff08;Input/Output Stream&#xff09;&#xff0c;它是…

【Python】函数的定义和调用、形参和实参、函数的返回值、多元赋值、全局和局部变量

文章目录 函数的定义函数的调用形参和实参函数的返回值一个 return多个 return多元赋值 变量作用域函数内的变量全局变量和局部变量修改全局变量 函数的定义 函数的定义&#xff1a;分配任务 def 函数名(形参列表):函数体return 返回值def&#xff1a;define&#xff0c;定义…

2024“钉耙编程”中国大学生算法设计超级联赛(8)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;杭电多校集训 本文用于记录回顾总结解题思路便于加深理解。 不是哥们&#xff0c;怎么我tm什么都不会。 &#x1f4e2;&…

计算机Java项目|基于SpringBoot的医院药品管理系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参…

大象机械臂myCobot 280 JN 2023和D435i相关环境配置

目录 一、安装Google拼音输入法二、安装CUDA 10.2三、安装conda管理环境四、配置D435i相机SDK五、安装realsense-ros 大象机器人的这款机械臂&#xff0c;用的Jetson nano做的主控&#xff0c;给的系统的ubuntu20&#xff0c;默认python版本是3.8。并且没有配置CUDA&#xff0c…

记录|SPC理解+SPC的监控看板

目录 前言一、Dashboard1.1 分布图1.2 控制图I-MR控制图&#xff1a;单值极差控制图Xbar-R图&#xff1a;均值极差控制图 1.3 趋势图 二、Xbar-R控制图判断异常的条件Xbar控制图R控制图 三、均值极差控制图【Xbar-R】3.1 基础理解XbarR最终绘制的Xbar-R图 3.2 如何看图看图顺序…

Linux下安装python与pip源配置(详细教程)

文章目录 Linux下安装python前置准备解压数据编译安装配置环境变量方式1&#xff1a;设置软连接方式2&#xff1a;添加PATH PIP源配置系统设置pip源临时设置pip源 问题解决缺少zlib包 Linux下安装python 前置准备 # 下载地址 https://www.python.org/ftp/python/3.6.8/# wget…

高精度夹治具的使用技巧和注意事项

在现代工业生产中&#xff0c;高精度夹治具扮演着至关重要的角色。它们能够确保工件在加工过程中的稳定性和精度&#xff0c;提高生产效率和产品质量。然而&#xff0c;要充分发挥高精度夹治具的优势&#xff0c;必须掌握正确的使用技巧和注意事项。以下是时利和整理的一些内容…

大数据-95 Spark 集群 SparkSQL Action与Transformation操作 详细解释与测试案例

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

关于lettuce的一次pipeline反向优化

起因是后台job对一批数据做大量的redis读写操作&#xff0c;为了提高job的执行速度&#xff0c;直接使用pipeline对一些不能批量读写的命令进行管道优化 简单介绍什么是lettuce Spring Boot自2.0版本开始默认使用Lettuce作为Redis的客户端&#xff08;注1&#xff09;。Lettu…

WEB渗透免杀篇-绕过

360白名单 需要足够的权限 360的扫描日志和设置白名单日志位置在&#xff1a;C:\Users[username]\AppData\Roaming\360Safe\360ScanLog 查看扫描日志内容可以查询到白名单文件 日志文件记录的是添加或移除白名单的时间、文件名、hash等信息&#xff0c;otc1为添加白名单&#…

SadTalker翻译与代码调试

文章目录 SadTalker原文翻译SadTalker&#xff1a;学习风格化音频驱动单幅图像说话人脸动画的真实 3D 运动系数Abstract1. Introduction2. Related Work3. Method3.1. Preliminary of 3D Face Model3.2. Motion Coefficients Generation through Audio3.3. 3D-aware Face Rende…

操作系统简介:设备管理

设备管理 1. 设备管理概述2. 设备管理技术通道技术DMA技术缓冲技术Spooling技术 3. 磁盘调度 设备管理是操作系统中最繁杂而且与硬件紧密相关的部分&#xff0c;不但要管理实际 I/O 操作的设备(如磁盘机、扫描仪、打印机、键盘和鼠标)&#xff0c;还要管理诸如设备控制器、DMA…