注:当执行操作时,会自动判断操作数类型并做相应转换,无法转换即抛异常
两种表达式执行方式:
- :需要传递 Map 格式参数
- :不需要传递 Map
两种模式:
- 以编译速度优先(默认):
- 以运行速度优先:
AviatorEvaluator.execute 内存溢出 :
- 背景:循环调用 时,JVM 非堆内存会慢慢增长,随着时间的推移,那段循环的代码被执行次数越多,非堆内存最终会因为只有增加没有释放而爆了
- 解决:如果表达式规模有限,都建议启用 cache 模式,除了 class 内存占用之外还可以提升性能
详情链接:循环调用AviatorEvaluator.execute的时候会出现问题
(1) 内置函数
- 详情可参考:https://juejin.cn/post/7002606430519853069
(2) 自定义函数
自定义函数要继承AbstractFunction类,重写目标方法
可阅读:https://ixyzero.com/blog/archives/3884.html
- 类型:数字类型,支持两种类型,分别对应 Java 的 Long 和 Double
- 整数被转换为 Long,浮点数被转换为 Double
- 不支持科学计数法,仅支持十进制
- 类型: 字符串类型,单引号或双引号括起来的文本串,如’hello world’
变量传入的 String 或 Character 将被转为 String 类型
- 类型: 常量 true 和 false,表示真值和假值,与 java 的 和 对应
- 类型: 正则表达式,以 括起来的字符串,如 ,内部实现为
- 变量类型: 与 Java 的变量命名规则相同,变量的值由用户传入
- 类型: 类似 java 的 ,但 可以参与 的比较
Aviator 规定:
- 除了 本身,任何类型都大于 nil
- 返回 true
- 用户传入的变量值若为 null,则将作为 nil 处理,nil 打印为 null
(1) 操作符列表
(2) 常量和变量
(3) 算术运算符
算术运算符:
其中:
- 仅能作用于Number类型
- 能用于 Number 类型和 String 类型
注:任何类型与String 相加,结果为 String
(4) 逻辑运算符
逻辑运算符包括:一元否定运算符 、逻辑与 、逻辑或
注:逻辑运算符的操作数只能为 Boolean
(5) 关系运算符
关系运算符包括:
注:
- 和 都执行短路规则
- 可以用作 Number之间、String之间、Pattern之间、Boolean之间、变量之间、其他类型与 nil 之间的关系比较
(6) 匹配运算符
匹配运算符 用于 String 和 Pattern 的匹配
注:
- 左操作数必须为 String,右操作数必须为 Pattern
- 匹配成功后,Pattern 的分组将存于变量 ,num 为分组索引
(7) 三元运算符
三元运算符 ,形式为
其中 bool 必须为结果为 Boolean 类型的表达式,而 exp1 和 exp2 可以为任何合法的 Aviator 表达式,并且不要求 exp1 和 exp2 返回的结果类型一致
Aviator 没有提供 语句
(1) 案例一:编译表达式
(2) 案例二:访问数组和集合
和数组用 和 , 用
(3) 案例三:三元比较符
(4) 案例四:正则表达式匹配
(5) 案例五:变量的语法糖衣
(6) 案例六:nil 对象
- nil 是 Aviator 的内置常量,表示空值
- nil 与 null 的区别:null 只能使用 ,而 nil 还可以使用
- 用户传入的变量若为 ,将自动以 替代
- 除了 nil 本身,任何对象都比 nil 大
(7) 案例七:日期比较
(8) 案例八:变量定义
MVEL 是一个功能强大的基于 Java 应用程序的表达式语言
特性:
- (1) 动态 JIT 优化器:当负载超过一个确保代码产生的阈值时,选择性地产生字节代码,减少内存使用量
新的静态类型检查和属性支持,允许集成类型安全表达
- (2) 错误报告的改善:包括行和列的错误信息
- (3) 新的脚本语言特征:包含函数定义,如:闭包、lambda定义、标准循环构造(for, while, do-while, do-until…)、空值安全导航操作、内联 with-context 运营 、易变的(isdef)的测试运营等等
- (4) 改进的集成功能:支持基础类型的个性化属性处理器,集成到 JIT 中
- (5) 更快的模板引擎:支持线性模板定义,宏定义和个性化标记定义
- (6) 新的交互式shell
- (7) 缺少可选类型安全
- (8) 集成不良:通过映射填入内容
- 没有字节码不能运作用字节码生成编译时间慢,还增加了可扩展性问题
- 不用字节码生成运行时执行非常慢
- (9) 内存消耗过大
- (10) Jar 巨大/依赖规模
与 java 不同, 是动态类型,即在源文件中没有类型限制
如:一条 表达式,可以是单个标识符,也可以是一个充满了方法调用和内部集合创建的庞大的布尔表达式
已集成了 规则表达式,后续可能集成
easy rules 是一个简单而强大的 java 规则引擎,有以下特性:
- 轻量级框架,学习成本低
- 基于 POJO
- 为定义业务引擎提供有用的抽象和简便的应用
- 从原始的规则组合成复杂的规则
主要的类或接口:
主要的注解:
- :可以标注 name 和 description 属性,每个rule的name要唯一,如果没有指定,则RuleProxy则默认取类名
- :条件判断,要求返回 boolean 值,表示是否满足条件
- :标注条件成立之后触发的方法
- :标注该 rule 的优先级,默认 ,值越小越优先
- :在客户端使用 put 方法向 Facts 中添加数据,在规则文件中通过 key 来得到相应的数据
Facts 的用法很像 Map,是客户端和规则文件之间通信的桥梁
(1) Java 方式
- 先创建规则并标注属性
- 然后客户端调用
(2) yml 方式
- 目录下新建
- 客户端调用