📋 目录


1. 概述

1.1 Aviator

Aviator 是一款由国内开发者开源的高性能、轻量级 Java 表达式求值引擎。它通过将表达式直接编译成 Java 字节码的方式来实现高性能的表达式求值,性能优于传统的解释器模式。

1.2 CEL-Java

CEL-Java(Common Expression Language for Java)是 Google 开源的通用表达式语言的 Java 实现。CEL 最初是为 Google Cloud Platform 的策略评估设计的,旨在提供一种安全、可移植且高效的表达式语言。


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. 基础语法 (1-2天): 了解基本运算符和表达式
  2. 函数使用 (2-3天): 掌握内置函数和自定义函数
  3. 高级特性 (3-5天): 学习闭包、Lambda、集合操作
  4. 性能优化 (3-5天): 了解编译缓存、性能调优

总计学习时间:约 1-2 周

5.2 CEL-Java 学习成本

难度:⭐⭐⭐ (中等)

挑战:

  • 📚 需要理解强类型系统
  • 🌐 文档以英文为主
  • 🔧 需要了解 CEL 的设计理念
  • 🎯 需要理解类型声明和验证

学习路径:

  1. 基础概念 (2-3天): 了解 CEL 的设计目标和类型系统
  2. 语法学习 (3-5天): 掌握表达式语法和操作符
  3. 类型系统 (3-5天): 理解类型声明和类型检查
  4. 高级特性 (5-7天): 学习自定义函数、扩展库
  5. 实践应用 (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 优缺点

✅ 优点
  1. 性能卓越

    • 编译成字节码执行,性能接近原生 Java
    • 高并发场景表现优秀
    • 内存占用低
  2. 易于使用

    • 语法类似 Java,学习成本低
    • API 简洁,快速上手
    • 丰富的中文文档和社区支持
  3. 功能丰富

    • 支持完整的编程特性(变量、函数、循环等)
    • 强大的集合处理能力
    • 支持 Lambda 和闭包
  4. 扩展性强

    • 自定义函数简单
    • 支持运算符重载
    • 灵活的变量解析机制
  5. 国内生态好

    • 社区活跃
    • 大量实践案例
    • 问题解答及时
❌ 缺点
  1. 类型安全性较弱

    • 动态类型可能导致运行时错误
    • 缺少编译期类型检查
  2. 安全性需要配置

    • 需要开发者手动配置安全选项
    • 默认情况下功能较为开放
  3. 可移植性差

    • 仅支持 Java 平台
    • 无法跨语言使用
  4. 国际化支持有限

    • 主要是中文社区
    • 国际知名度较低

11.2 CEL-Java 优缺点

✅ 优点
  1. 安全性高

    • 设计之初就考虑安全性
    • 强类型检查,避免类型错误
    • 沙箱执行,无副作用
  2. 可移植性好

    • 支持多种语言实现(Go, C++, Java 等)
    • 表达式可以跨平台共享
    • Google 生态集成良好
  3. 类型系统完善

    • 编译期类型检查
    • 完整的类型推导
    • 类型安全保证
  4. 设计规范

    • 清晰的语义定义
    • 确定性执行
    • 可预测的性能
  5. 企业级支持

    • Google 维护
    • 稳定的版本更新
    • 良好的文档
❌ 缺点
  1. 学习成本较高

    • 需要理解强类型系统
    • 概念较为抽象
    • 中文资料较少
  2. 功能受限

    • 不支持变量声明
    • 不支持复杂控制结构
    • 不支持自定义运算符
  3. 扩展较复杂

    • 自定义函数需要类型声明
    • 扩展难度较大
    • 样板代码较多
  4. 性能相对较低

    • 解释执行,性能低于编译型
    • 不适合高频调用场景
  5. 社区生态

    • 国内使用案例较少
    • 社区相对较小

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

CEL-Java

13.2 社区资源

Aviator

CEL-Java

13.3 相关项目

基于 Aviator 的项目

  • LiteFlow: 轻量级规则引擎
  • Easy Rules: 规则引擎框架

基于 CEL 的项目

  • Kubernetes Admission Control
  • Google Cloud Platform IAM
  • Envoy Proxy

14. 结论

AviatorCEL-Java 各有千秋,选择哪个取决于具体的应用场景和需求:

核心差异总结

维度 Aviator CEL-Java
设计理念 性能至上,功能丰富 安全优先,类型严格
最佳场景 高性能计算、规则引擎 策略评估、权限控制
学习曲线 平缓,易上手 陡峭,需理解类型系统
社区生态 国内活跃 国际化,Google 支持
性能表现 卓越(编译型) 良好(解释型)
安全性 良好(需配置) 优秀(设计保证)

最终建议

  1. 性能敏感型应用 → 选择 Aviator
  2. 安全敏感型应用 → 选择 CEL-Java
  3. 快速开发需求 → 选择 Aviator
  4. 跨平台需求 → 选择 CEL-Java
  5. 复杂业务逻辑 → 选择 Aviator
  6. 简单策略评估 → 选择 CEL-Java
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐