Spring SpEL在Flink中的应用-SpEL详解

 

前言

  Spring 表达式语言 Spring Expression Language(简称 SpEL )是一个支持运行时查询和操做对象图的表达式语言 。 语法相似于 EL 表达式 ,但提供了显式方法调用和基本字符串模板函数等额外特性。SpEL 在许多组件中都得到了广泛应用,如 Spring Data、Spring Security、Spring Web Flow 等。它提供了一种非常灵活的方式来查询和操作对象图,从而简化了复杂的业务逻辑和数据操作。本系列文章介绍SpEL与Flink结合应用。


一、SpEL主要功能

  • 属性查询和设置:可以查询和设置对象的属性。例如,#root.name 查询根对象的 "name" 属性。
  • 方法调用:可以调用对象的任意方法。例如,#root.someMethod() 调用根对象的 "someMethod" 方法。
  • 条件表达式:可以使用条件表达式,如 ?>, ?, <, <=, >=, !=, == 来判断值。
  • 布尔和关系运算符:可用于布尔和关系运算。
  • 集合操作:可以用来操作集合,如 size(), contains(), any, all, isEmpty 等。
  • 自定义函数:可以注册自定义函数,并在 SpEL 表达式中调用它们。
  • 类型转换:SpEL 支持类型转换,例如 as 关键字可以用来转换类型。
  • 正则表达式:可以使用正则表达式进行模式匹配。
  • 解析 JSON:SpEL 可以解析 JSON 字符串并查询其内容。

二、POM依赖

首先在 pom.xml 中加入依赖:

<dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.2.0.RELEASE</version>
</dependency>

二、SpEL应用

1.解析字面量

    private void evaluateLiteralExpresssions() {Expression exp = parser.parseExpression("'Hello World'");String message = (String) exp.getValue();System.out.println(message);exp = parser.parseExpression("88");Integer value = exp.getValue(Integer.class);System.out.println(value*2);}

2.直接文本上调用方法

示例展示了在字符串上直接调用Java String类的public方法。

private void methodInvocationOnLiterals() {Expression exp = parser.parseExpression("'Hello World'.concat('!')");String message = (String) exp.getValue();println(message);exp = parser.parseExpression("'Hello World'.length()");Integer size = exp.getValue(Integer.class);println(size);exp = parser.parseExpression("'Hello World'.split(' ')[0]");message = (String)exp.getValue();println(message);}

3、访问对象属性和方法

	private void accessingObjectProperties() {User user = new User("John", "Doe",  true, "john.doe@acme.com",30);Expression exp = parser.parseExpression("firstName");println((String)exp.getValue(user));exp = parser.parseExpression("isAdmin()==false");boolean isAdmin = exp.getValue(user, Boolean.class);println(isAdmin);exp = parser.parseExpression("email.split('@')[0]");String emailId = exp.getValue(user, String.class);println(emailId);exp = parser.parseExpression("age");Integer age = exp.getValue(user, Integer.class);println(age);}

4、Json表达式

    public static void jsonExpress(){JSONObject json = new JSONObject();json.put("age",20);StandardEvaluationContext conetxt = new StandardEvaluationContext(json);SpelExpressionParser parser = new SpelExpressionParser();String el="get('age')>10";el="['age']>10";Expression exp = parser.parseExpression(el);Boolean bb=(Boolean)exp.getValue(conetxt);System.out.println(bb);}

5、Flink Row表达式

    public static void rowExpress(){Row row = Row.of("name4", 6000, 104.5d);StandardEvaluationContext conetxt = new StandardEvaluationContext(row);SpelExpressionParser parser = new SpelExpressionParser();String el="getField(2)+getField(2)";Expression exp = parser.parseExpression(el);Object value = exp.getValue(conetxt);Double bb=(Double)value;System.out.println(bb);}

6、调用自定义函数

注册自定义函数,并调用。日期比较代码示例:

    public static void compareDate(){StandardEvaluationContext context = new StandardEvaluationContext(new SpelMethodUtil());context.setVariable("dateOne", new Date());
//        context.setVariable("dateTwo", "2022-01-01");//SpEL ParserExpressionParser parser = new SpelExpressionParser();Expression exp = parser.parseExpression("compareDate(#dateOne, \"2024-01-01\")");Object value = exp.getValue(context);System.out.println(value);}

自定义函数类

public class SpelMethodUtil {public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DATE_FORMAT = "yyyy-MM-dd";public static final String TIME_FORMAT = "HH:mm:ss";public static Integer compareDate(Date date, String strDate){Integer result;if(date==null&& StringUtils.isBlank(strDate)){return 0;}else{if(date==null || StringUtils.isBlank(strDate)){return -2;}}String trimDate=strDate.trim();String format = findFormat(trimDate);Date date2 = stringToDate(trimDate, format);result=date.compareTo(date2);return result;}public static Integer compareDate(Date first, Date second){if(first==null&& second==null){return 0;}else{if(first==null || second==null){return -2;}}return first.compareTo(second);}public static Date stringToDate(String dateStr,String format){SimpleDateFormat sdf = new SimpleDateFormat(format);Date date=null;try {date= sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return date;}/*** 查找与输入的字符型日期相匹配的format* @param strDate* @return*/public static String findFormat(String strDate){String result=null;String trimDate=strDate.trim();int len=trimDate.length();String dateRegex = "";if(len==TIMESTAMP_FORMAT.length()){dateRegex = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$";if(trimDate.matches(dateRegex)){result=TIMESTAMP_FORMAT;}}else if(len==DATE_FORMAT.length()){dateRegex = "^\\d{4}-\\d{2}-\\d{2}$";if(trimDate.matches(dateRegex)){result=DATE_FORMAT;}}else if(len==TIME_FORMAT.length()){dateRegex = "^\\d{2}:\\d{2}:\\d{2}$";if(trimDate.matches(dateRegex)){result=TIME_FORMAT;}}else{throw  new RuntimeException("不可识别的日期格式!"+strDate);}return result;}public static Integer addAge(Integer age){return age+4;}
}

七、执行各种操作符(比较、逻辑、算术)

SpEl支持下面几种操作:

关系比较操作:==, !=, <, <=, >, >=
逻辑操作: and, or, not
算术操作: +, -, /, *, %, ^

    private void operators() {User user = new User("John", "Doe", true,"john.doe@acme.com",  30);Expression exp = parser.parseExpression("age > 18");println(exp.getValue(user,Boolean.class));exp = parser.parseExpression("age < 18 and isAdmin()");println(exp.getValue(user,Boolean.class));}

总结

通过示例介绍了SpEl中多种应用示例。大家可以利用这些功能实现更加灵活的功能应用。

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

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

相关文章

HTML+JavaScript-02

数组 JavaScript中的数组用于在单一变量存储多个值&#xff0c;其实跟java中的数组是一样的&#xff0c;都是通过索引来访问这些值的。 创建数组 方式一&#xff1a;&#xff08;推荐&#xff09; var cars ["北京现代", "丰田", "五菱宏光"…

EDA-数据探索-pandas自带可视化-iris

# 加载yellowbrick数据集 import os import pandas as pd FIXTURES os.path.join(os.getcwd(), "data") df pd.read_csv(os.path.join(FIXTURES,"iris.csv")) df.head()sepal_lengthsepal_widthpetal_lengthpetal_widthspecies05.13.51.40.2setosa14.93…

最新AI系统ChatGPT网站系统源码,支持AI绘画,GPT语音对话,ChatFile文档对话总结,DALL-E3文生图,MJ绘画局部编辑重绘

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

springboot aop 自定义注解形式

引入pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>自定义注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; impo…

数仓建设学习路线(三)元数据管理

什么是元数据&#xff1f; 简单来说就是描述数据的数据&#xff0c;更直白来说就是描述表名、表制作者、表字段、表生命周期、表存粗等信息的数据 元数据该如何管理 工具化 开源&#xff1a; 可通过atlas获取表依赖及信息做二次开发&#xff0c;或者完成可视化界面 平台化&am…

【网络安全 -> 防御与保护】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 网络安全——防御与保护 &#xff08;一&#xff09;.信息安全概述 &#xff08;二&#xff09;.防火墙组网

从k8s当中学习go cli脚手架开发利器-cobra

1.前言 大部分的项目都会引入cobra来作为项目的命令行解析工具&#xff0c;k8s当中大量使用cobra&#xff0c;学习借鉴一下k8s当中是如何使用cobra&#xff0c;在此记录一下。 2.cobra简介 cobra是一个提供简单接口来创建强大的现代CLI界面的库类似git & git tools&…

计组与原理:系统总线

大家好啊&#xff0c;这里来到计组第二部分内容&#xff1a;系统总线 跳转上一篇&#xff1a;计组原理&#xff1a;系统概论与基本组成 系统总线 1.总线的基本概念单总线结构框图面向 CPU 的双总线结构框图以存储器为中心的双总线结构框图 2.总线的分类片内总线系统总线通信总线…

Linux之权限(内容详细,细节满满)

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 Linux 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力 目录 一.前言 二.权限修改的两种方法 …

Python学习02—Python开发环境的配置

1.Python语言的简单概述 Python的诞生离不开一个人&#xff0c;他就是Guido van Rossum&#xff0c;他在1989年的圣诞节期间&#xff0c;在荷兰的阿姆斯特丹度假&#xff0c;为了打发假期时间&#xff0c;就想着设计一种编程语言&#xff0c;后期便诞生了Python Python语言拥…

掌握技术脉搏:程序员如何在技术变革中保持领先,避免被裁员

笔者刚入行IT业的时候&#xff0c;有个前辈老猿工就语重心长的说&#xff0c;写代码要与时俱进&#xff0c;永远不能停止学习&#xff0c;如果不能时刻走在前面&#xff0c;就会被淘汰。哪天感觉到力不从心&#xff0c;就要考虑努力往管理层走啦。随着计算机技术和互联网技术的…

MySQL-B-tree和B+tree区别

B-tree&#xff08;平衡树&#xff09;和Btree&#xff08;平衡树的一种变种&#xff09;是两种常见的树状数据结构&#xff0c;用于构建索引以提高数据库的查询性能。它们在一些方面有相似之处&#xff0c;但也有一些关键的区别。以下是B-tree和Btree的主要区别&#xff1a; …

Java Server-Sent Events通信

Server-Sent Events特点与优势 后端可以向前端发送信息&#xff0c;类似于websocket&#xff0c;但是websocket是双向通信&#xff0c;但是sse为单向通信&#xff0c;服务器只能向客户端发送文本信息&#xff0c;效率比websocket高。 单向通信&#xff1a;SSE只支持服务器到客…

openssl3.2/test/certs - 003 - genroot “Root CA“ root-key2 root-cert2

文章目录 openssl3.2/test/certs - 003 - genroot "Root CA" root-key2 root-cert2概述笔记END openssl3.2/test/certs - 003 - genroot “Root CA” root-key2 root-cert2 概述 索引贴 > openssl3.2 - 官方demo学习 - test - certs 笔记 // openssl3.2/test/…

Leetcode—22.括号生成【中等】

2023每日刷题&#xff08;七十九&#xff09; Leetcode—22.括号生成 算法思想 实现代码 class Solution { public:vector<string> generateParenthesis(int n) {vector<string> ans;int m n * 2;string path(m, 0);function<void(int, int)> dfs [&…

小红书多模态团队建立新「扩散模型」:解码脑电波,高清还原人眼所见

近些年&#xff0c;研究人员们对探索大脑如何解读视觉信息&#xff0c;并试图还原出原始图像一直孜孜不倦。去年一篇被 CVPR 录用的论文&#xff0c;通过扩散模型重建视觉影像&#xff0c;给出了非常炸裂的效果—— AI 不光通过脑电波知道你看到了什么&#xff0c;并且帮你画了…

Acwing4993. FEB

题目 有一个长度为 N 的字符串 S&#xff0c;其中的每个字符要么是 B&#xff0c;要么是 E。 我们规定 S 的价值等于其中包含的子串 BB 以及子串 EE 的数量之和。 例如&#xff0c;BBBEEE 中包含 22 个 BB 以及 22 个 EE&#xff0c;所以 BBBEEE 的价值等于 44。 我们想要计…

技术浪潮中的职业变革:程序员面临的裁员挑战与应对策略

目录 前言 冲破时空壁垒&#xff1a;探索技术变革的酷时代&#xff01; 逆境成长&#xff1a;一个互联网人战胜失业困境的故事 裁员的双面影响&#xff1a;挑战与机遇 应对裁员潮危机&#xff1a;程序员的超级英雄之路 前言 惊人的新闻传来&#xff0c;一对来自中国的工程师…

基于神经网络的电力系统的负荷预测

一、背景介绍&#xff1a; 电力系统负荷预测是生产部门的重要工作之一&#xff0c;通过准确的负荷预测&#xff0c;可以经济合理地安排机组的启停、减少旋转备用容量、合理安排检修计划、降低发电成本和提高经济效益。负荷预测按预测的时间可以分为长期、中期和短期负荷预测。…

MySQL慢查询日志

慢查询日志 MySQL的慢查询日志是用来记录MySQL响应时间超过阈值的语句&#xff0c;即为超过long_query_time值得sql语句 默认没有开启慢查询(如果开启慢查询会导致性能降低) 慢日志配置 查看是否开启慢查询 show variables like %slow_query_log%; 开启慢查询 #只对当前数据库生…