Aviator 与 CEL-Java 表达式引擎对比分析
📋 目录
1. 概述
1.1 Aviator
Aviator 是一款由国内开发者开源的高性能、轻量级 Java 表达式求值引擎。它通过将表达式直接编译成 Java 字节码的方式来实现高性能的表达式求值,性能优于传统的解释器模式。
- 官方仓库: https://github.com/killme2008/aviatorscript
- 开发者: killme2008
- 首次发布: 2010年
- 许可证: Apache License 2.0
1.2 CEL-Java
CEL-Java(Common Expression Language for Java)是 Google 开源的通用表达式语言的 Java 实现。CEL 最初是为 Google Cloud Platform 的策略评估设计的,旨在提供一种安全、可移植且高效的表达式语言。
- 官方仓库: https://github.com/google/cel-java
- 开发者: Google
- 首次发布: 2018年
- 许可证: Apache License 2.0
2. 核心特性对比
| 特性 | Aviator | CEL-Java |
|---|---|---|
| 设计目标 | 高性能、轻量级的表达式求值引擎 | 安全、可移植、高效的通用表达式语言 |
| 执行方式 | 编译成 Java 字节码执行 | 解释执行(带优化) |
| 类型系统 | 动态类型,自动类型转换 | 强类型系统,严格类型检查 |
| 语法风格 | 类 Java 语法,易于理解 | 类 C 语法,简洁明了 |
| 变量绑定 | 支持动态变量绑定 | 支持强类型变量绑定 |
| 安全性 | 运行期安全性较高 | 设计之初就注重安全性,提供细粒度控制 |
| 可移植性 | 仅支持 Java 平台 | 跨语言支持(Go, C++, Java 等) |
| 社区生态 | 国内社区活跃,中文文档丰富 | Google 维护,国际化社区 |
3. 应用场景
3.1 Aviator 适用场景
✅ 规则引擎
- 动态业务规则配置与执行
- 复杂的规则判断和决策树
- 风控系统的规则计算
✅ 公式计算
- 动态公式配置和计算
- 财务计算、统计分析
- 科学计算和数学表达式求值
✅ 动态脚本控制
- 配置化的业务逻辑
- 工作流引擎的条件判断
- 动态代码生成
✅ 集合数据处理
- 复杂的数据过滤和转换
- 批量数据计算
- 高性能数据处理
3.2 CEL-Java 适用场景
✅ 配置管理
- 动态配置评估
- 环境变量和参数验证
- 配置文件的条件逻辑
✅ 策略评估
- 权限和访问控制策略
- API 网关的路由规则
- 云平台的策略管理
✅ 安全场景
- 需要防止恶意代码注入的场景
- 用户输入的表达式评估
- 沙箱环境的表达式执行
✅ 跨平台集成
- 需要在多种语言间共享表达式逻辑
- 微服务架构中的一致性规则
- 与 Google Cloud Platform 集成
4. 性能对比
4.1 Aviator 性能特点
优势:
- ⚡ 极高性能: 编译成字节码执行,性能接近原生 Java 代码
- 🚀 高并发支持: 在高并发场景下表现出色
- 💾 低内存占用: 编译后的表达式可以重用,内存占用低
性能数据(参考):
简单表达式求值: ~1-5 微秒
复杂表达式求值: ~10-50 微秒
编译时间: ~1-10 毫秒
适用于:
- 高频率调用的场景(每秒数万次以上)
- 对性能要求极高的系统
- 需要低延迟响应的场景
4.2 CEL-Java 性能特点
优势:
- 🛡️ 安全优先: 牺牲部分性能换取更高的安全性
- 📊 可预测性: 表达式执行时间可控
- 🔍 类型检查: 编译期类型检查避免运行时错误
性能数据(参考):
简单表达式求值: ~10-50 微秒
复杂表达式求值: ~50-200 微秒
编译时间: ~5-20 毫秒
适用于:
- 安全性要求高于性能的场景
- 中等频率调用的场景(每秒数千次)
- 需要类型安全的场景
4.3 性能对比总结
| 场景 | Aviator | CEL-Java | 推荐 |
|---|---|---|---|
| 高并发计算 | 优秀 | 良好 | Aviator |
| 复杂表达式 | 优秀 | 良好 | Aviator |
| 安全沙箱 | 良好 | 优秀 | CEL-Java |
| 跨语言调用 | 不支持 | 优秀 | CEL-Java |
| 内存占用 | 低 | 中等 | Aviator |
5. 学习成本
5.1 Aviator 学习成本
难度:⭐⭐ (容易)
优势:
- 📖 语法类似 Java,Java 开发者容易上手
- 🇨🇳 丰富的中文文档和示例
- 💡 社区活跃,问题解答快速
- 🎓 学习曲线平缓
学习路径:
- 基础语法 (1-2天): 了解基本运算符和表达式
- 函数使用 (2-3天): 掌握内置函数和自定义函数
- 高级特性 (3-5天): 学习闭包、Lambda、集合操作
- 性能优化 (3-5天): 了解编译缓存、性能调优
总计学习时间:约 1-2 周
5.2 CEL-Java 学习成本
难度:⭐⭐⭐ (中等)
挑战:
- 📚 需要理解强类型系统
- 🌐 文档以英文为主
- 🔧 需要了解 CEL 的设计理念
- 🎯 需要理解类型声明和验证
学习路径:
- 基础概念 (2-3天): 了解 CEL 的设计目标和类型系统
- 语法学习 (3-5天): 掌握表达式语法和操作符
- 类型系统 (3-5天): 理解类型声明和类型检查
- 高级特性 (5-7天): 学习自定义函数、扩展库
- 实践应用 (5-7天): 集成到实际项目中
总计学习时间:约 2-4 周
5.3 学习资源对比
| 资源类型 | Aviator | CEL-Java |
|---|---|---|
| 官方文档 | ⭐⭐⭐⭐⭐ 详细 | ⭐⭐⭐⭐ 完整但较抽象 |
| 中文资料 | ⭐⭐⭐⭐⭐ 丰富 | ⭐⭐ 较少 |
| 示例代码 | ⭐⭐⭐⭐⭐ 大量 | ⭐⭐⭐ 中等 |
| 社区支持 | ⭐⭐⭐⭐⭐ 国内活跃 | ⭐⭐⭐⭐ 国际社区 |
| 视频教程 | ⭐⭐⭐⭐ 较多 | ⭐⭐ 较少 |
6. 语法与表达式
6.1 Aviator 语法特性
基本类型
// 数字类型
long num1 = 100;
double num2 = 3.14;
bigint num3 = 99999999999999999999N;
decimal num4 = 3.14159265358979323846M;
// 字符串
string str = "Hello World";
// 布尔值
boolean flag = true;
// 正则表达式
regex pattern = /\d+/;
// nil 值
nil value = nil;
运算符
// 算术运算符: +, -, *, /, %, **(幂运算)
1 + 2 * 3
// 关系运算符: >, >=, <, <=, ==, !=
a > b
// 逻辑运算符: &&, ||, !
a > 0 && b < 10
// 位运算符: &, |, ^, <<, >>
a & b
// 三元运算符
a > b ? a : b
// 正则匹配: =~, !~
str =~ /^\d+$/
// 成员运算符: in
"key" in map
集合操作
// 数组/列表
let list = [1, 2, 3, 4, 5];
// Map
let map = { "name": "John", "age": 30 };
// 序列函数
seq.map(list, lambda(x) -> x * 2 end)
seq.filter(list, lambda(x) -> x > 2 end)
seq.reduce(list, lambda(acc, x) -> acc + x end, 0)
函数定义
// Lambda 表达式
let add = lambda(a, b) -> a + b end;
// 函数调用
add(1, 2)
// 闭包
let makeCounter = lambda()
let count = 0;
return lambda() -> count = count + 1 end;
end;
控制结构
// if-else
if (a > b) {
return a;
} else {
return b;
}
// for 循环
for x in list {
println(x);
}
// while 循环
while (count < 10) {
count = count + 1;
}
6.2 CEL-Java 语法特性
基本类型
// 整数
int64: 42
uint64: 42u
// 浮点数
double: 3.14
// 字符串
string: "Hello World"
// 布尔值
bool: true, false
// 字节数组
bytes: b"hello"
// null 值
null
运算符
// 算术运算符: +, -, *, /, %
1 + 2 * 3
// 关系运算符: <, <=, >=, >, ==, !=
a > b
// 逻辑运算符: &&, ||, !
a > 0 && b < 10
// 三元运算符
a > b ? a : b
// 成员运算符: in
"key" in map
// 字符串操作
str.startsWith("prefix")
str.contains("substr")
集合操作
// 列表
[1, 2, 3, 4, 5]
// Map
{"name": "John", "age": 30}
// 列表推导式
[1, 2, 3].map(x, x * 2)
[1, 2, 3].filter(x, x > 1)
// 成员访问
list[0]
map.name
map["name"]
函数调用
// 内置函数
size([1, 2, 3]) // 返回 3
type(42) // 返回 "int"
// 字符串函数
"hello".size()
"hello".startsWith("he")
// 类型转换
int(3.14)
string(42)
double("3.14")
宏和扩展
// has 宏 - 检查字段是否存在
has(message.field)
// all 和 exists 宏 - 量词
[1, 2, 3].all(x, x > 0)
[1, 2, 3].exists(x, x > 2)
// matches 函数 - 正则匹配
"123".matches(r'\d+')
6.3 语法对比总结
| 特性 | Aviator | CEL-Java |
|---|---|---|
| 变量声明 | 支持 (let) | 不支持,只能通过上下文传入 |
| 函数定义 | 支持 (lambda) | 不支持,只能使用内置或注册的函数 |
| 控制结构 | 支持 (if/for/while) | 仅支持三元运算符 |
| 闭包 | 支持 | 不支持 |
| 正则表达式 | 原生支持 | 通过函数支持 |
| 集合操作 | 丰富的 seq 库 | 内置 map/filter/all/exists |
| 类型转换 | 自动转换 | 需要显式转换 |
| 语法复杂度 | 较复杂,功能丰富 | 简洁,功能聚焦 |
7. 函数支持
7.1 Aviator 内置函数
数学函数
// 基本数学函数
math.abs(-5) // 绝对值
math.sqrt(16) // 平方根
math.pow(2, 3) // 幂运算
math.round(3.14) // 四舍五入
math.ceil(3.14) // 向上取整
math.floor(3.14) // 向下取整
math.max(1, 2, 3) // 最大值
math.min(1, 2, 3) // 最小值
math.sin(0.5) // 正弦
math.cos(0.5) // 余弦
math.tan(0.5) // 正切
字符串函数
string.length("hello") // 字符串长度
string.substring("hello", 0, 2) // 子字符串
string.indexOf("hello", "l") // 查找位置
string.contains("hello", "ll") // 包含判断
string.startsWith("hello", "he") // 前缀判断
string.endsWith("hello", "lo") // 后缀判断
string.split("a,b,c", ",") // 分割字符串
string.join([1, 2, 3], ",") // 连接字符串
string.replace("hello", "l", "L") // 替换
string.trim(" hello ") // 去除空格
string.toLowerCase("HELLO") // 转小写
string.toUpperCase("hello") // 转大写
集合函数
seq.map(list, lambda(x) -> x * 2 end) // 映射
seq.filter(list, lambda(x) -> x > 2 end) // 过滤
seq.reduce(list, lambda(acc, x) -> acc + x end, 0) // 归约
seq.count(list) // 计数
seq.every(list, lambda(x) -> x > 0 end) // 全部满足
seq.some(list, lambda(x) -> x > 5 end) // 部分满足
seq.sort(list) // 排序
seq.reverse(list) // 反转
seq.distinct(list) // 去重
日期时间函数
date.now() // 当前时间戳
date.format(timestamp, "yyyy-MM-dd") // 格式化日期
date.parse("2024-01-01", "yyyy-MM-dd") // 解析日期
date.year(timestamp) // 获取年份
date.month(timestamp) // 获取月份
date.day(timestamp) // 获取日期
类型判断函数
type(value) // 获取类型
is_def(variable) // 是否定义
is_nil(value) // 是否为 nil
is_number(value) // 是否为数字
is_string(value) // 是否为字符串
is_bool(value) // 是否为布尔值
自定义函数
// 注册自定义函数
AviatorEvaluator.addFunction(new AbstractFunction() {
@Override
public String getName() {
return "myFunction";
}
@Override
public AviatorObject call(Map<String, Object> env,
AviatorObject arg1,
AviatorObject arg2) {
// 函数实现
return new AviatorLong(result);
}
});
7.2 CEL-Java 内置函数
通用函数
// 类型判断
type(value) // 返回值的类型
// 大小获取
size([1, 2, 3]) // 返回 3
size("hello") // 返回 5
size({"a": 1}) // 返回 1
字符串函数
// 字符串操作
"hello".startsWith("he") // 前缀判断
"hello".endsWith("lo") // 后缀判断
"hello".contains("ll") // 包含判断
"hello".matches(r'\w+') // 正则匹配
// 字符串转换
string(42) // 转字符串
数值函数
// 类型转换
int(3.14) // 转整数
double("3.14") // 转浮点数
uint(42) // 转无符号整数
// 数值判断
int(42) > 0
集合函数
// 列表操作
[1, 2, 3].size() // 大小
[1, 2, 3].map(x, x * 2) // 映射
[1, 2, 3].filter(x, x > 1) // 过滤
[1, 2, 3].all(x, x > 0) // 全部满足
[1, 2, 3].exists(x, x > 2) // 存在满足
[1, 2, 3].exists_one(x, x == 2) // 恰好一个满足
// Map 操作
{"a": 1, "b": 2}.size() // 大小
has({"a": 1}.a) // 字段存在判断
时间函数(需要扩展库)
// 时间戳
timestamp("2024-01-01T00:00:00Z")
// 持续时间
duration("1h30m")
// 时间比较
timestamp1 < timestamp2
timestamp1 + duration("1h")
自定义函数
// 注册自定义函数
CelBuilder celBuilder = CelFactory.standardCelBuilder()
.addFunctions(
CelFunctionDecl.newFunctionDeclaration("myFunction",
CelOverloadDecl.newMemberOverload("myFunction_string",
SimpleType.STRING,
ImmutableList.of(SimpleType.STRING, SimpleType.INT)
)
)
)
.addFunctionBindings(
CelRuntime.CelFunctionBinding.from(
"myFunction_string",
String.class, Long.class,
(str, num) -> str.repeat(num.intValue())
)
);
7.3 函数支持对比
| 类别 | Aviator | CEL-Java |
|---|---|---|
| 数学函数 | ⭐⭐⭐⭐⭐ 非常丰富 | ⭐⭐ 基础运算 |
| 字符串函数 | ⭐⭐⭐⭐⭐ 功能完整 | ⭐⭐⭐⭐ 常用功能 |
| 集合函数 | ⭐⭐⭐⭐⭐ seq 库功能强大 | ⭐⭐⭐⭐ 宏支持良好 |
| 日期函数 | ⭐⭐⭐⭐ 内置支持 | ⭐⭐⭐ 需要扩展库 |
| 类型函数 | ⭐⭐⭐⭐ 完整支持 | ⭐⭐⭐⭐⭐ 强类型系统 |
| 正则表达式 | ⭐⭐⭐⭐⭐ 原生支持 | ⭐⭐⭐ 函数支持 |
| 自定义扩展 | ⭐⭐⭐⭐⭐ 简单灵活 | ⭐⭐⭐ 需要理解类型系统 |
8. 安全性
8.1 Aviator 安全性
安全特性
✅ 沙箱执行
- 表达式在受限环境中执行
- 不能直接访问系统资源
✅ 函数白名单
- 可以控制允许使用的函数
- 自定义函数需要显式注册
✅ 超时控制
- 支持设置表达式执行超时时间
- 防止无限循环或长时间运行
⚠️ 潜在风险
- 动态类型可能导致意外的类型转换
- 复杂表达式可能消耗大量资源
- 需要开发者自己控制变量访问权限
安全配置示例
// 设置执行超时
AviatorEvaluatorInstance instance = AviatorEvaluator.newInstance();
instance.setOption(Options.EVAL_TIMEOUT_MS, 1000); // 1秒超时
// 禁用某些功能
instance.setOption(Options.FEATURE_SET, Feature.asSet(
Feature.Assignment, // 禁用赋值
Feature.Lambda, // 禁用Lambda
Feature.NewInstance // 禁用对象创建
));
// 限制循环次数
instance.setOption(Options.MAX_LOOP_COUNT, 10000);
8.2 CEL-Java 安全性
安全特性
✅ 设计时即考虑安全
- 不支持任意代码执行
- 不能访问文件系统或网络
✅ 强类型检查
- 编译期类型检查
- 避免运行时类型错误
✅ 确定性执行
- 相同输入保证相同输出
- 无副作用
✅ 资源限制
- 表达式复杂度限制
- 执行时间可控
✅ 无反射机制
- 不能动态调用任意方法
- 只能使用预定义的函数
安全配置示例
// 创建安全的 CEL 环境
CelBuilder celBuilder = CelFactory.standardCelBuilder()
// 启用检查模式
.setStandardMacros(CelStandardMacro.STANDARD_MACROS)
.addVar("user", SimpleType.DYN)
// 限制递归深度
.setOptions(
CelOptions.newBuilder()
.comprehensionMaxIterations(1000) // 限制列表推导次数
.build()
);
Cel cel = celBuilder.build();
// 编译期类型检查
CelAbstractSyntaxTree ast = cel.compile("user.age > 18").getAst();
// 运行时求值
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder().build();
CelRuntime.Program program = celRuntime.createProgram(ast);
8.3 安全性对比
| 安全特性 | Aviator | CEL-Java |
|---|---|---|
| 代码注入防护 | ⭐⭐⭐ 良好 | ⭐⭐⭐⭐⭐ 优秀 |
| 类型安全 | ⭐⭐ 动态类型 | ⭐⭐⭐⭐⭐ 强类型 |
| 资源限制 | ⭐⭐⭐⭐ 可配置 | ⭐⭐⭐⭐⭐ 内置限制 |
| 超时控制 | ⭐⭐⭐⭐⭐ 支持 | ⭐⭐⭐ 有限支持 |
| 沙箱隔离 | ⭐⭐⭐ 良好 | ⭐⭐⭐⭐⭐ 优秀 |
| 副作用控制 | ⭐⭐⭐ 需要开发者注意 | ⭐⭐⭐⭐⭐ 无副作用设计 |
结论:
- CEL-Java 在安全性方面更胜一筹,特别适合需要执行用户输入表达式的场景
- Aviator 的安全性也不错,但需要开发者更多的配置和注意
9. 扩展性
9.1 Aviator 扩展性
自定义函数
// 方式1: 继承 AbstractFunction
public class MyFunction extends AbstractFunction {
@Override
public String getName() {
return "myFunc";
}
@Override
public AviatorObject call(Map<String, Object> env,
AviatorObject arg1) {
String str = FunctionUtils.getStringValue(arg1, env);
return new AviatorString(str.toUpperCase());
}
}
// 注册函数
AviatorEvaluator.addFunction(new MyFunction());
// 使用
AviatorEvaluator.execute("myFunc('hello')"); // 返回 "HELLO"
// 方式2: Lambda 表达式(Java 8+)
AviatorEvaluator.addFunction(new AbstractFunction() {
@Override
public String getName() {
return "add10";
}
@Override
public AviatorObject call(Map<String, Object> env,
AviatorObject arg1) {
Number num = FunctionUtils.getNumberValue(arg1, env);
return AviatorNumber.valueOf(num.longValue() + 10);
}
});
自定义运算符
// 重载运算符
AviatorEvaluator.addOpFunction(OperatorType.ADD, new AbstractFunction() {
@Override
public AviatorObject call(Map<String, Object> env,
AviatorObject arg1,
AviatorObject arg2) {
// 自定义加法逻辑
return new AviatorString(arg1.getValue(env) + " + " + arg2.getValue(env));
}
});
自定义变量解析
// 实现自定义的变量解析器
public class CustomPropertyAccessor implements PropertyAccessor {
@Override
public Object get(Object target, String name) {
// 自定义属性访问逻辑
if (target instanceof MyObject) {
return ((MyObject) target).getProperty(name);
}
return null;
}
}
// 注册
AviatorEvaluator.getInstance().addPropertyAccessor(MyObject.class,
new CustomPropertyAccessor());
9.2 CEL-Java 扩展性
自定义函数
// 定义函数签名
CelFunctionDecl myFunctionDecl = CelFunctionDecl.newFunctionDeclaration(
"myFunc",
CelOverloadDecl.newGlobalOverload(
"myFunc_string",
SimpleType.STRING,
ImmutableList.of(SimpleType.STRING)
)
);
// 实现函数逻辑
CelRuntime.CelFunctionBinding myFunctionBinding =
CelRuntime.CelFunctionBinding.from(
"myFunc_string",
String.class,
(String str) -> str.toUpperCase()
);
// 创建 CEL 环境
Cel cel = CelFactory.standardCelBuilder()
.addFunctionDeclarations(myFunctionDecl)
.build();
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder()
.addFunctionBindings(myFunctionBinding)
.build();
自定义类型
// 定义自定义类型
StructTypeReference personType = StructTypeReference.create("Person");
// 添加类型字段
Cel cel = CelFactory.standardCelBuilder()
.addMessageTypes(Person.class)
.addVar("person", personType)
.build();
// 使用
String expression = "person.name == 'John' && person.age > 18";
CelAbstractSyntaxTree ast = cel.compile(expression).getAst();
自定义宏
// 定义自定义宏
CelMacro myMacro = new CelMacro() {
@Override
public String getKey() {
return "customMacro";
}
@Override
public CelExpr expand(CelExpr target, List<CelExpr> args, long exprId) {
// 宏展开逻辑
return CelExpr.ofCall(exprId, "expandedFunction", args);
}
};
// 注册宏
Cel cel = CelFactory.standardCelBuilder()
.addMacros(myMacro)
.build();
9.3 扩展性对比
| 扩展方式 | Aviator | CEL-Java |
|---|---|---|
| 自定义函数 | ⭐⭐⭐⭐⭐ 非常简单 | ⭐⭐⭐ 需要类型声明 |
| 自定义运算符 | ⭐⭐⭐⭐⭐ 支持 | ❌ 不支持 |
| 自定义类型 | ⭐⭐⭐ 通过 Java 类 | ⭐⭐⭐⭐ 完整的类型系统 |
| 变量解析 | ⭐⭐⭐⭐⭐ 灵活 | ⭐⭐⭐ 需要预定义 |
| 函数重载 | ⭐⭐⭐ 有限支持 | ⭐⭐⭐⭐⭐ 完整支持 |
| 扩展难度 | ⭐⭐ 容易 | ⭐⭐⭐⭐ 较难 |
结论:
- Aviator 扩展性更强,更灵活,适合需要大量自定义的场景
- CEL-Java 扩展性较强,但需要理解类型系统,适合需要类型安全的场景
10. 代码示例
10.1 Aviator 完整示例
示例1: 基本使用
import com.googlecode.aviator.AviatorEvaluator;
import java.util.HashMap;
import java.util.Map;
public class AviatorBasicExample {
public static void main(String[] args) {
// 简单表达式
Object result1 = AviatorEvaluator.execute("1 + 2 * 3");
System.out.println("Result: " + result1); // 输出: 7.0
// 带变量的表达式
Map<String, Object> env = new HashMap<>();
env.put("a", 10);
env.put("b", 20);
Object result2 = AviatorEvaluator.execute("a + b", env);
System.out.println("Result: " + result2); // 输出: 30.0
// 字符串操作
env.put("name", "World");
Object result3 = AviatorEvaluator.execute("'Hello, ' + name", env);
System.out.println("Result: " + result3); // 输出: Hello, World
// 逻辑判断
env.put("age", 25);
Object result4 = AviatorEvaluator.execute("age >= 18 ? 'Adult' : 'Minor'", env);
System.out.println("Result: " + result4); // 输出: Adult
}
}
示例2: 规则引擎应用
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import java.util.*;
/**
* 规则引擎示例 - 用户信用评分系统
*/
public class RuleEngineExample {
// 规则列表
private static final List<Rule> RULES = Arrays.asList(
new Rule("优秀信用", "score >= 750 && income > 100000 && age >= 25", 1),
new Rule("良好信用", "score >= 650 && score < 750 && income > 50000", 2),
new Rule("一般信用", "score >= 550 && score < 650", 3),
new Rule("信用不足", "score < 550 || income < 30000", 4)
);
static class Rule {
String name;
Expression expression;
int level;
Rule(String name, String expr, int level) {
this.name = name;
this.expression = AviatorEvaluator.compile(expr); // 编译表达式
this.level = level;
}
}
public static void main(String[] args) {
// 用户数据
Map<String, Object> user = new HashMap<>();
user.put("score", 720);
user.put("income", 80000);
user.put("age", 30);
// 执行规则匹配
for (Rule rule : RULES) {
Boolean matched = (Boolean) rule.expression.execute(user);
if (matched) {
System.out.println("匹配规则: " + rule.name);
System.out.println("信用等级: " + rule.level);
break;
}
}
}
}
示例3: 自定义函数
import com.googlecode.aviator.*;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.*;
import java.util.Map;
/**
* 自定义函数示例
*/
public class CustomFunctionExample {
/**
* 自定义函数: 检查字符串是否为有效的手机号
*/
static class IsValidPhoneFunction extends AbstractFunction {
@Override
public String getName() {
return "isValidPhone";
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1) {
String phone = FunctionUtils.getStringValue(arg1, env);
boolean valid = phone != null && phone.matches("^1[3-9]\\d{9}$");
return AviatorBoolean.valueOf(valid);
}
}
/**
* 自定义函数: 计算BMI指数
*/
static class BmiFunction extends AbstractFunction {
@Override
public String getName() {
return "bmi";
}
@Override
public AviatorObject call(Map<String, Object> env,
AviatorObject arg1,
AviatorObject arg2) {
Number weight = FunctionUtils.getNumberValue(arg1, env);
Number height = FunctionUtils.getNumberValue(arg2, env);
double bmi = weight.doubleValue() /
Math.pow(height.doubleValue() / 100, 2);
return AviatorDouble.valueOf(bmi);
}
}
public static void main(String[] args) {
// 注册自定义函数
AviatorEvaluator.addFunction(new IsValidPhoneFunction());
AviatorEvaluator.addFunction(new BmiFunction());
// 使用自定义函数
Map<String, Object> env = new HashMap<>();
env.put("phone", "13812345678");
Boolean validPhone = (Boolean) AviatorEvaluator.execute(
"isValidPhone(phone)", env);
System.out.println("手机号有效: " + validPhone);
// 计算BMI
env.put("weight", 70);
env.put("height", 175);
Double bmiValue = (Double) AviatorEvaluator.execute(
"bmi(weight, height)", env);
System.out.println("BMI指数: " + String.format("%.2f", bmiValue));
// 组合使用
String healthRule = "bmi(weight, height) >= 18.5 && bmi(weight, height) <= 24.9 ? '健康' : '需要注意'";
String result = (String) AviatorEvaluator.execute(healthRule, env);
System.out.println("健康状况: " + result);
}
}
示例4: 集合处理
import com.googlecode.aviator.AviatorEvaluator;
import java.util.*;
/**
* 集合处理示例
*/
public class CollectionExample {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
// 数据列表
List<Map<String, Object>> users = Arrays.asList(
createUser("张三", 25, 8000),
createUser("李四", 30, 12000),
createUser("王五", 28, 9000),
createUser("赵六", 35, 15000)
);
env.put("users", users);
// 过滤: 年龄大于25的用户
Object filtered = AviatorEvaluator.execute(
"seq.filter(users, lambda(u) -> u.age > 25 end)", env);
System.out.println("年龄>25的用户: " + filtered);
// 映射: 获取所有用户名
Object names = AviatorEvaluator.execute(
"seq.map(users, lambda(u) -> u.name end)", env);
System.out.println("用户名列表: " + names);
// 归约: 计算总工资
Object totalSalary = AviatorEvaluator.execute(
"seq.reduce(users, lambda(sum, u) -> sum + u.salary end, 0)", env);
System.out.println("总工资: " + totalSalary);
// 组合操作: 年龄大于25的用户的平均工资
String avgSalaryExpr =
"let filtered = seq.filter(users, lambda(u) -> u.age > 25 end); " +
"let total = seq.reduce(filtered, lambda(sum, u) -> sum + u.salary end, 0); " +
"let count = seq.count(filtered); " +
"total / count";
Object avgSalary = AviatorEvaluator.execute(avgSalaryExpr, env);
System.out.println("平均工资: " + avgSalary);
}
private static Map<String, Object> createUser(String name, int age, int salary) {
Map<String, Object> user = new HashMap<>();
user.put("name", name);
user.put("age", age);
user.put("salary", salary);
return user;
}
}
10.2 CEL-Java 完整示例
示例1: 基本使用
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.compiler.CelCompiler;
import dev.cel.compiler.CelCompilerFactory;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntimeFactory;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import java.util.HashMap;
import java.util.Map;
/**
* CEL-Java 基本使用示例
*/
public class CelBasicExample {
public static void main(String[] args) throws Exception {
// 创建编译器
CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder()
.addVar("a", com.google.api.expr.v1alpha1.Type.newBuilder()
.setPrimitive(com.google.api.expr.v1alpha1.Type.PrimitiveType.INT64)
.build())
.addVar("b", com.google.api.expr.v1alpha1.Type.newBuilder()
.setPrimitive(com.google.api.expr.v1alpha1.Type.PrimitiveType.INT64)
.build())
.build();
// 编译表达式
CelAbstractSyntaxTree ast = celCompiler.compile("a + b * 3").getAst();
// 创建运行时
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder().build();
CelRuntime.Program program = celRuntime.createProgram(ast);
// 准备变量
Map<String, Object> variables = new HashMap<>();
variables.put("a", 10L);
variables.put("b", 20L);
// 执行表达式
Object result = program.eval(variables);
System.out.println("Result: " + result); // 输出: 70
}
}
示例2: 策略评估系统
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.compiler.*;
import dev.cel.runtime.*;
import com.google.api.expr.v1alpha1.Type;
import java.util.*;
/**
* 策略评估系统示例 - API 访问控制
*/
public class PolicyEvaluationExample {
static class Policy {
String name;
String description;
CelRuntime.Program program;
Policy(String name, String description, CelRuntime.Program program) {
this.name = name;
this.description = description;
this.program = program;
}
boolean evaluate(Map<String, Object> context) {
try {
Object result = program.eval(context);
return result instanceof Boolean && (Boolean) result;
} catch (Exception e) {
return false;
}
}
}
public static void main(String[] args) throws Exception {
// 创建编译器
CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder()
.addVar("user", CelTypes.createMap(
CelTypes.STRING,
CelTypes.DYN
))
.addVar("resource", CelTypes.createMap(
CelTypes.STRING,
CelTypes.DYN
))
.build();
// 创建运行时
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder().build();
// 定义策略规则
List<Policy> policies = new ArrayList<>();
// 策略1: 管理员可以访问所有资源
policies.add(new Policy(
"管理员全权限",
"管理员角色可以访问所有资源",
celRuntime.createProgram(
celCompiler.compile("user.role == 'admin'").getAst()
)
));
// 策略2: 用户可以访问自己的资源
policies.add(new Policy(
"用户访问自己的资源",
"用户只能访问自己创建的资源",
celRuntime.createProgram(
celCompiler.compile(
"user.role == 'user' && user.id == resource.owner_id"
).getAst()
)
));
// 策略3: 访客只能读取公开资源
policies.add(new Policy(
"访客读取公开资源",
"访客只能读取标记为公开的资源",
celRuntime.createProgram(
celCompiler.compile(
"user.role == 'guest' && resource.is_public == true"
).getAst()
)
));
// 测试场景1: 管理员访问
Map<String, Object> context1 = new HashMap<>();
context1.put("user", createMap("id", "001", "role", "admin"));
context1.put("resource", createMap("id", "res-001", "owner_id", "002"));
System.out.println("=== 场景1: 管理员访问 ===");
evaluatePolicies(policies, context1);
// 测试场景2: 用户访问自己的资源
Map<String, Object> context2 = new HashMap<>();
context2.put("user", createMap("id", "001", "role", "user"));
context2.put("resource", createMap("id", "res-001", "owner_id", "001"));
System.out.println("\n=== 场景2: 用户访问自己的资源 ===");
evaluatePolicies(policies, context2);
// 测试场景3: 访客访问公开资源
Map<String, Object> context3 = new HashMap<>();
context3.put("user", createMap("id", "003", "role", "guest"));
context3.put("resource", createMap("id", "res-003", "owner_id", "001", "is_public", true));
System.out.println("\n=== 场景3: 访客访问公开资源 ===");
evaluatePolicies(policies, context3);
}
private static void evaluatePolicies(List<Policy> policies, Map<String, Object> context) {
boolean allowed = false;
for (Policy policy : policies) {
if (policy.evaluate(context)) {
System.out.println("✅ 允许访问 - 策略: " + policy.name);
System.out.println(" 描述: " + policy.description);
allowed = true;
break;
}
}
if (!allowed) {
System.out.println("❌ 拒绝访问 - 没有匹配的策略");
}
}
private static Map<String, Object> createMap(Object... keyValues) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < keyValues.length; i += 2) {
map.put((String) keyValues[i], keyValues[i + 1]);
}
return map;
}
}
示例3: 自定义函数
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOverloadDecl;
import dev.cel.compiler.*;
import dev.cel.runtime.*;
import com.google.common.collect.ImmutableList;
import java.util.*;
/**
* CEL-Java 自定义函数示例
*/
public class CelCustomFunctionExample {
public static void main(String[] args) throws Exception {
// 声明自定义函数
CelFunctionDecl toUpperFunction = CelFunctionDecl.newFunctionDeclaration(
"toUpper",
CelOverloadDecl.newGlobalOverload(
"toUpper_string",
CelTypes.STRING,
ImmutableList.of(CelTypes.STRING)
)
);
CelFunctionDecl isValidEmailFunction = CelFunctionDecl.newFunctionDeclaration(
"isValidEmail",
CelOverloadDecl.newGlobalOverload(
"isValidEmail_string",
CelTypes.BOOL,
ImmutableList.of(CelTypes.STRING)
)
);
// 创建编译器
CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder()
.addFunctionDeclarations(toUpperFunction, isValidEmailFunction)
.addVar("email", CelTypes.STRING)
.addVar("name", CelTypes.STRING)
.build();
// 实现函数逻辑
CelRuntime.CelFunctionBinding toUpperBinding =
CelRuntime.CelFunctionBinding.from(
"toUpper_string",
String.class,
(String str) -> str.toUpperCase()
);
CelRuntime.CelFunctionBinding isValidEmailBinding =
CelRuntime.CelFunctionBinding.from(
"isValidEmail_string",
String.class,
(String email) -> email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$")
);
// 创建运行时
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder()
.addFunctionBindings(toUpperBinding, isValidEmailBinding)
.build();
// 编译并执行表达式
CelAbstractSyntaxTree ast1 = celCompiler.compile("toUpper(name)").getAst();
CelRuntime.Program program1 = celRuntime.createProgram(ast1);
Map<String, Object> vars1 = new HashMap<>();
vars1.put("name", "hello world");
System.out.println("toUpper: " + program1.eval(vars1));
// 验证邮箱
CelAbstractSyntaxTree ast2 = celCompiler.compile("isValidEmail(email)").getAst();
CelRuntime.Program program2 = celRuntime.createProgram(ast2);
Map<String, Object> vars2 = new HashMap<>();
vars2.put("email", "test@example.com");
System.out.println("isValidEmail: " + program2.eval(vars2));
// 组合使用
String expression = "isValidEmail(email) ? toUpper('valid') : 'invalid'";
CelAbstractSyntaxTree ast3 = celCompiler.compile(expression).getAst();
CelRuntime.Program program3 = celRuntime.createProgram(ast3);
System.out.println("组合结果: " + program3.eval(vars2));
}
}
示例4: 列表处理
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.compiler.*;
import dev.cel.runtime.*;
import java.util.*;
/**
* CEL-Java 列表处理示例
*/
public class CelListExample {
public static void main(String[] args) throws Exception {
// 创建编译器
CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder()
.addVar("users", CelTypes.createList(
CelTypes.createMap(CelTypes.STRING, CelTypes.DYN)
))
.build();
// 创建运行时
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder().build();
// 准备数据
List<Map<String, Object>> users = Arrays.asList(
createUser("张三", 25, 8000),
createUser("李四", 30, 12000),
createUser("王五", 28, 9000),
createUser("赵六", 35, 15000)
);
Map<String, Object> context = new HashMap<>();
context.put("users", users);
// 示例1: 检查是否所有用户年龄都大于20
String expr1 = "users.all(u, u.age > 20)";
Object result1 = evaluate(celCompiler, celRuntime, expr1, context);
System.out.println("所有用户年龄>20: " + result1);
// 示例2: 检查是否存在工资大于10000的用户
String expr2 = "users.exists(u, u.salary > 10000)";
Object result2 = evaluate(celCompiler, celRuntime, expr2, context);
System.out.println("存在工资>10000的用户: " + result2);
// 示例3: 过滤年龄大于25的用户
String expr3 = "users.filter(u, u.age > 25)";
Object result3 = evaluate(celCompiler, celRuntime, expr3, context);
System.out.println("年龄>25的用户: " + result3);
// 示例4: 映射获取所有用户名
String expr4 = "users.map(u, u.name)";
Object result4 = evaluate(celCompiler, celRuntime, expr4, context);
System.out.println("用户名列表: " + result4);
// 示例5: 复杂查询 - 年龄在25-35之间且工资大于8000的用户数量
String expr5 = "users.filter(u, u.age >= 25 && u.age <= 35 && u.salary > 8000).size()";
Object result5 = evaluate(celCompiler, celRuntime, expr5, context);
System.out.println("符合条件的用户数: " + result5);
}
private static Map<String, Object> createUser(String name, int age, int salary) {
Map<String, Object> user = new HashMap<>();
user.put("name", name);
user.put("age", age);
user.put("salary", salary);
return user;
}
private static Object evaluate(CelCompiler compiler,
CelRuntime runtime,
String expression,
Map<String, Object> context) throws Exception {
CelAbstractSyntaxTree ast = compiler.compile(expression).getAst();
CelRuntime.Program program = runtime.createProgram(ast);
return program.eval(context);
}
}
10.3 示例对比总结
| 特性 | Aviator 示例 | CEL-Java 示例 |
|---|---|---|
| 代码简洁度 | ⭐⭐⭐⭐⭐ 非常简洁 | ⭐⭐⭐ 需要更多样板代码 |
| 类型声明 | ⭐⭐⭐⭐⭐ 无需声明 | ⭐⭐ 需要显式类型声明 |
| 学习曲线 | ⭐⭐⭐⭐⭐ 平缓 | ⭐⭐⭐ 需要理解类型系统 |
| 扩展灵活性 | ⭐⭐⭐⭐⭐ 非常灵活 | ⭐⭐⭐ 需要更多配置 |
| 执行效率 | ⭐⭐⭐⭐⭐ 极高 | ⭐⭐⭐⭐ 良好 |
| 类型安全 | ⭐⭐⭐ 运行时检查 | ⭐⭐⭐⭐⭐ 编译期检查 |
11. 优缺点总结
11.1 Aviator 优缺点
✅ 优点
-
性能卓越
- 编译成字节码执行,性能接近原生 Java
- 高并发场景表现优秀
- 内存占用低
-
易于使用
- 语法类似 Java,学习成本低
- API 简洁,快速上手
- 丰富的中文文档和社区支持
-
功能丰富
- 支持完整的编程特性(变量、函数、循环等)
- 强大的集合处理能力
- 支持 Lambda 和闭包
-
扩展性强
- 自定义函数简单
- 支持运算符重载
- 灵活的变量解析机制
-
国内生态好
- 社区活跃
- 大量实践案例
- 问题解答及时
❌ 缺点
-
类型安全性较弱
- 动态类型可能导致运行时错误
- 缺少编译期类型检查
-
安全性需要配置
- 需要开发者手动配置安全选项
- 默认情况下功能较为开放
-
可移植性差
- 仅支持 Java 平台
- 无法跨语言使用
-
国际化支持有限
- 主要是中文社区
- 国际知名度较低
11.2 CEL-Java 优缺点
✅ 优点
-
安全性高
- 设计之初就考虑安全性
- 强类型检查,避免类型错误
- 沙箱执行,无副作用
-
可移植性好
- 支持多种语言实现(Go, C++, Java 等)
- 表达式可以跨平台共享
- Google 生态集成良好
-
类型系统完善
- 编译期类型检查
- 完整的类型推导
- 类型安全保证
-
设计规范
- 清晰的语义定义
- 确定性执行
- 可预测的性能
-
企业级支持
- Google 维护
- 稳定的版本更新
- 良好的文档
❌ 缺点
-
学习成本较高
- 需要理解强类型系统
- 概念较为抽象
- 中文资料较少
-
功能受限
- 不支持变量声明
- 不支持复杂控制结构
- 不支持自定义运算符
-
扩展较复杂
- 自定义函数需要类型声明
- 扩展难度较大
- 样板代码较多
-
性能相对较低
- 解释执行,性能低于编译型
- 不适合高频调用场景
-
社区生态
- 国内使用案例较少
- 社区相对较小
12. 选型建议
12.1 选择 Aviator 的场景
推荐在以下场景使用 Aviator:
✅ 高性能要求
- 需要极高的表达式求值性能
- 高并发、高频率调用场景
- 对延迟敏感的系统
✅ 功能丰富性
- 需要复杂的业务逻辑处理
- 需要集合处理和数据转换
- 需要使用 Lambda 和闭包
✅ 快速开发
- 团队对 Java 熟悉
- 需要快速上手和开发
- 需要丰富的中文文档支持
✅ 灵活扩展
- 需要大量自定义函数
- 需要自定义运算符
- 需要灵活的业务适配
✅ 纯 Java 环境
- 只在 Java 平台使用
- 不需要跨语言支持
典型应用:
- 规则引擎
- 风控系统
- 报表计算
- 动态配置
- 数据处理管道
12.2 选择 CEL-Java 的场景
推荐在以下场景使用 CEL-Java:
✅ 安全性优先
- 需要执行用户输入的表达式
- 需要沙箱隔离
- 防止代码注入攻击
✅ 类型安全
- 需要编译期类型检查
- 需要类型安全保证
- 避免运行时类型错误
✅ 跨平台需求
- 需要在多种语言间共享表达式
- 微服务架构的一致性规则
- 与 Google Cloud 集成
✅ 策略评估
- 权限和访问控制
- 配置管理
- API 网关规则
✅ 确定性要求
- 需要可预测的执行时间
- 无副作用的纯函数
- 确定性的结果
典型应用:
- 策略引擎
- 权限控制
- 配置验证
- API 网关
- 云平台集成
12.3 选型决策树
是否需要极高性能?
├─ 是 → Aviator
└─ 否
└─ 是否需要执行用户输入的表达式?
├─ 是 → CEL-Java (安全性更好)
└─ 否
└─ 是否需要跨语言支持?
├─ 是 → CEL-Java
└─ 否
└─ 是否需要复杂的编程特性?
├─ 是 → Aviator (功能更丰富)
└─ 否
└─ 是否需要强类型检查?
├─ 是 → CEL-Java
└─ 否 → Aviator (更易用)
12.4 混合使用建议
在某些场景下,可以考虑混合使用:
场景1: 分层架构
- 前端/API层使用 CEL-Java(安全性)
- 后端/计算层使用 Aviator(性能)
场景2: 不同业务模块
- 权限控制使用 CEL-Java
- 业务计算使用 Aviator
场景3: 渐进式迁移
- 新功能使用更合适的引擎
- 旧功能保持现有引擎
12.5 性能与安全权衡
| 需求权重 | 性能优先 | 平衡 | 安全优先 |
|---|---|---|---|
| 高并发计算 | Aviator | Aviator | CEL-Java |
| 用户输入表达式 | CEL-Java | CEL-Java | CEL-Java |
| 内部规则引擎 | Aviator | Aviator | 都可以 |
| 权限策略 | Aviator | CEL-Java | CEL-Java |
| 配置验证 | Aviator | CEL-Java | CEL-Java |
12.6 团队技能考虑
| 团队特点 | 推荐选择 |
|---|---|
| Java 新手团队 | Aviator(更易学) |
| 注重类型安全 | CEL-Java(强类型) |
| 需要国际化 | CEL-Java(多语言文档) |
| 偏好中文文档 | Aviator(中文资源丰富) |
| 有 Google 生态经验 | CEL-Java(生态集成) |
13. 参考资源
13.1 官方资源
Aviator
- GitHub: https://github.com/killme2008/aviatorscript
- 官方文档: https://www.yuque.com/boyan-avfmj/aviatorscript
- Maven:
com.googlecode.aviator:aviator
CEL-Java
- GitHub: https://github.com/google/cel-java
- CEL 规范: https://github.com/google/cel-spec
- Codelab: https://github.com/google/cel-java/tree/main/codelab
- Maven:
dev.cel:cel
13.2 社区资源
Aviator
- Gitee 镜像: https://gitee.com/mirrors/AviatorScript
- 博客文章、掘金、CSDN 等平台有大量中文教程
CEL-Java
- Google Cloud 文档: https://cloud.google.com/iam/docs/conditions-overview
- Kubernetes CEL: https://kubernetes.io/docs/reference/using-api/cel/
13.3 相关项目
基于 Aviator 的项目
- LiteFlow: 轻量级规则引擎
- Easy Rules: 规则引擎框架
基于 CEL 的项目
- Kubernetes Admission Control
- Google Cloud Platform IAM
- Envoy Proxy
14. 结论
Aviator 和 CEL-Java 各有千秋,选择哪个取决于具体的应用场景和需求:
核心差异总结
| 维度 | Aviator | CEL-Java |
|---|---|---|
| 设计理念 | 性能至上,功能丰富 | 安全优先,类型严格 |
| 最佳场景 | 高性能计算、规则引擎 | 策略评估、权限控制 |
| 学习曲线 | 平缓,易上手 | 陡峭,需理解类型系统 |
| 社区生态 | 国内活跃 | 国际化,Google 支持 |
| 性能表现 | 卓越(编译型) | 良好(解释型) |
| 安全性 | 良好(需配置) | 优秀(设计保证) |
最终建议
- 性能敏感型应用 → 选择 Aviator
- 安全敏感型应用 → 选择 CEL-Java
- 快速开发需求 → 选择 Aviator
- 跨平台需求 → 选择 CEL-Java
- 复杂业务逻辑 → 选择 Aviator
- 简单策略评估 → 选择 CEL-Java
更多推荐


所有评论(0)