Solon Expression Language (SnEL):轻量高效的Java表达式引擎
一、SnEL 是什么?
Solon Expression Language(简称SnEL)是 Solon 生态体系中的轻量级表达式引擎,专为Java开发者设计。它采用独特的"求值表达式"模型,通过简洁的语法实现复杂逻辑处理,同时保持极高的执行效率和安全性。
项目地址:
二、核心特性解析
1. 安全可靠的表达式引擎
- 无副作用设计:禁止
new实例化、控制语句等危险操作 - 上下文隔离:通过
StandardContext严格管控变量访问范围
2. 丰富的表达式能力
// 复杂逻辑表达式示例
String expr = """
((age > 18 AND salary < 5000) OR NOT isMarried)
AND tags IN ['vip','premium']
OR level == 'gold'""";
支持功能主要包括:
- 基础运算:算术、比较、逻辑运算
- 集合操作:IN/NOT IN集合判断
- 嵌套访问:多级对象属性/方法调用
- 静态方法:直接调用类静态方法
- 三元运算:条件表达式支持
更多参考官网:《SnEL 求值表达式语法和能力说明》
3. 独创的模板引擎
双模式模板处理:
// 求值表达式模板
SnEL.evalTmpl("订单总额:#{order.amount * 0.95}");
// 属性表达式模板(带默认值)
SnEL.evalTmpl("配置参数:${server.timeout:3000}");
三、企业级功能深度解析
1. 上下文增强方案
// 标准Map上下文
Map<String,Object> ctx = new HashMap<>();
ctx.put("user", userService.getCurrent());
// 增强型Bean上下文
StandardContext context = new StandardContext(userEntity);
context.properties(configProps); // 绑定配置属性
// 虚拟root访问
SnEL.eval("root.id > 1000", context);
2. 多场景表达式转换
基于AST的通用转换接口:
Expression expr = SnEL.parse("age > 18 AND status=='active'");
// 转换为Redis查询语法
String redisFilter = RedisFilterTransformer.getInstance().transform(expr);
// 转换为Elasticsearch DSL
Map<String,Object> esQuery = ElasticsearchFilterTransformer.getInstance().transform(expr);
// 输出语法树结构
PrintUtil.printTree(expr);
| 转换器类型 | 输出示例 | 应用场景 |
|---|---|---|
| Redis | (@age:[18 +inf] @status:{active}) |
缓存查询 |
| Milvus | ((metadata["age"] > 18) and (metadata["status"] == "active")) |
向量数据库 |
| Elasticsearch | {bool={must=[{range={age={gt=18}}}, {term={status={value=active}}}]}} |
全文检索 |
| SQL | WHERE age > 18 AND status='active' |
数据库查询 |
四、典型应用场景
- 动态规则引擎:金融风控规则配置
- 智能路由:微服务调用条件路由
- 低代码平台:表单校验逻辑动态配置
- 数据分析:实时数据过滤与计算
五、快速入门
1. 添加依赖
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-expression</artifactId>
<version>最新版本</version>
</dependency>
2. 基础用法示例
public class Demo {
public static void main(String[] args) {
Map<String,Object> context = new HashMap<>();
context.put("price", 99.5);
context.put("discount", 0.8);
Object result = SnEL.eval("price * discount > 50", context);
System.out.println("是否符合条件:" + result);
}
}
3. 性能优化建议
- 复用解析结果:对固定表达式使用 SnEL.parse() 缓存 AST
- 上下文优化:复杂对象优先使用 StandardContext
- 避免频繁解析:高并发场景预编译表达式
六、企业实践案例
案例1:电商促销系统
// 动态计算促销条件
String rule = """
(user.level IN ['VIP','SVIP'] OR order.amount > 1000)
AND inventory.stock > 0
AND NOT blacklist.contains(user.id)""";
Boolean rst = SnEL.eval(rule, context);
案例2:物联网数据处理
// 设备数据过滤规则
String filter = """
(data.temperature > 38.5 OR data.humidity < 20)
AND meta.deviceType == 'medical'""";
// 转换为MQTT Topic过滤语法(需要自已定制 IotTransformer)
String mqttFilter = IotTransformer.transform(SnEL.parse(filter));
Solon Expression Language (SnEL):轻量高效的Java表达式引擎的更多相关文章
- Vue.js:轻量高效的前端组件化方案
转发一篇尤老师对vue.js的介绍,了解vue.js的来龙去脉.不过现在已经是2.0了,也有添加一些新的东西,当然有些东西也改了. Vue.js:轻量高效的前端组件化方案 Vue.js 是我在2014 ...
- Vue.js:轻量高效的前端组件化方案(转载)
摘要:Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.在前端纷繁复杂的生态中,Vue.js有幸受到一定程度的关注,目前在GitHub上已经有5000+的star.本文将从各方面对Vue ...
- 【转】Vue.js:轻量高效的前端组件化方案
摘要:Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.在前端纷繁复杂的生态中,Vue.js有幸受到一定程度的关注,目前在GitHub上已经有5000+的star.本文将从各方面对Vue ...
- 轻量高效的开源JavaScript插件和库 【转】
图片 布局 轮播图 弹出层 音频视频 编辑器 字符串 表单 存储 动画 时间 其它 加载器 构建工具 测试 包管理器 CDN 图片 baguetteBox.js - 是一个简单易用的响应式图像灯箱效果 ...
- 2016年31款轻量高效的开源JavaScript插件和库
目前有很多网站设计师和开发者喜欢使用由JavaScript开发的插件和库,但同时面临一个苦恼的问题:它们中的大多数实在是太累赘而且常常降低网站的性能.其实,其中也有不少轻量级的插件和库,它们不仅轻巧有 ...
- 2016年31款轻量高效的开源 JavaScript 插件和库
目前有很多网站设计师和开发者喜欢使用由JavaScript开发的插件和库,但同时面临一个苦恼的问题:它们中的大多数实在是太累赘而且常常降低网站的性能.其实,其中也有不少轻量级的插件和库,它们不仅轻巧有 ...
- 2016 年 31 款轻量高效的开源 JavaScript 插件和库
目前有很多网站设计师和开发者喜欢使用由JavaScript开发的插件和库,但同时面临一个苦恼的问题:它们中的大多数实在是太累赘而且常常降低网站的性能.其实,其中也有不少轻量级的插件和库,它们不仅轻巧有 ...
- 【Juicer】 一个高效、轻量的前端 (Javascript) 模板引擎
引用地址:http://juicer.name/docs/docs_zh_cn.html * 一个完整的例子 HTML 代码: <script id="tpl" type=& ...
- 推荐轻量高效无依赖的开源JS插件和库
目录 图片 布局 音频视频 编辑器 轮播图 弹出层 表单 存储 动画 时间 其它 CDN 图片 baguetteBox.js - 是一个简单易用的响应式图像灯箱效果脚本.demo Lightgalle ...
- 39行代码实现JS HTML模板(轻量+高效+易用)
otmpl 是一个轻量级前端模版(仅有39行无压缩代码,支持缓存),所用指令仅需[#...#]和{#...#},前者包含需要输出html语句,后者包含js变量. 支持javascript完整语法,你可 ...
随机推荐
- 查看Linux防火墙状态
环境:VMware.CentOS8从centos7开始使用systemctl.firewalld来管理服务和程序,包括了service和chkconfig.防火墙状态:systemctl status ...
- 在Java集合框架中,`Set`接口是一个重要的接口,它表示一个不包含重复元素的集合。常见的`Set`实现类有`HashSet`、`LinkedHashSet`和`TreeSet`。下面是关于`Set`接口的一些基本用法和方法介绍:
常用实现类 HashSet: 基于哈希表实现,元素无序. 插入.删除.查找操作的时间复杂度为O(1). LinkedHashSet: 继承自HashSet,并使用双向链表来维护元素的插入顺序. 保留元 ...
- ASP.NET之设置默认文档
通常... <!--Web.config--> <configuration> <!--指定默认文档 Start Author:JAnnn Time:2015-01-10 ...
- 🎀Java线程池创建
简介 Java 手动创建线程池 代码 package com.zk.app.utils; import com.google.common.util.concurrent.ThreadFactoryB ...
- 🎀idea获取当前项目git仓库地址
简介 在idea中快速获取当前项目的远程仓库地址 方案一 右键项目 选择Git 选择Manage Remotes 弹框中的URL就是远程仓库地址 方案二 打开terminal 命令行 直接Git命令查 ...
- Asp.net mvc基础(十)判断是否是ajax请求
通过Request.IsAjaxRequest()方法进行判断是否是ajax的请求,true是ajax的请求,false不是ajax的请求 后端: 前端: 效果: 使用Request.IsAjaxRe ...
- C#/.NET/.NET Core技术前沿周刊 | 第 35 期(2025年4.14-4.20)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- Web前端入门第 39 问:细说 CSS position 定位布局
CSS 的定位属性 position 可以把元素从文档流中拧出来,让其显示在其他位置. 但凡元素定位属性加身,元素位置便不再受文档流控制,这时候什么 flex.grid 都不好使了,定位的元素已然跳出 ...
- 解析异步消息加上(→_→)@SuppressLint("HandlerLeak")
在主线程又Handler处理消息出现时这样写会有警告 private Handler handler = new Handler(){ @Override public void handleMess ...
- Java 数据库开发总结
数据库连接.设计以及备份技巧集锦 JDBC操作各种数据库经验技巧集萃 Java 数据库连接(JDBC)由一组用 Java 编程语言编写的类和接口组成.JDBC 为工具/数据库开发人员提供了一个标准的 ...