规则引擎 之 Aviator
Aviator 是一个高性能、轻量级的 Java 表达式求值引擎,由 Dianping(大众点评)开源。它支持将字符串形式的表达式(如 "a + b > 10 ? 'pass' : 'fail'")在运行时动态解析并执行,广泛应用于规则引擎、风控系统、配置化逻辑、报表计算等场景。
与 QLExpress 类似,但 Aviator 设计更简洁、性能更高(尤其在数值计算方面),且天然支持函数式编程风格。
一、核心原理
1. 执行流程
Aviator 的执行分为三个阶段:
[字符串表达式]
↓ (词法分析)
[Tokens: 变量、操作符、数字、括号...]
↓ (语法分析 + 编译为字节码)
[AviatorFunction(内部表示)]
↓ (解释执行 / JIT 优化)
[执行结果]
- 编译期:将表达式编译为内部的
AviatorFunction对象(可缓存) - 运行期:传入变量上下文(Map),调用
execute()返回结果 - 无反射依赖:通过预定义的操作符和函数实现,避免运行时反射开销
✅ 关键优势:
- 表达式只编译一次,多次执行效率极高
- 类型推断:自动处理数字类型(int/long/double)
- 沙箱安全:默认无法访问任意 Java 方法(需显式注册)
2. 核心特性
| 特性 | 说明 |
|---|---|
| 高性能 | 单表达式 QPS 可达 50w+(远超 Groovy/JSR223) |
| 轻量级 | JAR 包仅 ~300KB,无第三方依赖 |
| 丰富语法 | 支持算术、逻辑、三元、正则、集合操作等 |
| 自定义函数 | 可注册 Java Lambda 或方法作为函数 |
| 安全可控 | 默认禁止反射,仅允许白名单函数 |
| 内置函数库 | 提供 string, math, regex, date 等常用函数 |
二、快速入门示例
1. 添加 Maven 依赖
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.4.1</version> <!-- 推荐最新版 -->
</dependency>
GitHub 地址:https://github.com/killme2008/aviator
2. 基础表达式计算
import com.googlecode.aviator.AviatorEvaluator;
public class BasicExample {
public static void main(String[] args) {
// 直接执行(每次解析,不推荐生产使用)
Object result = AviatorEvaluator.execute("1 + 2 * 3");
System.out.println(result); // 7
// 编译后复用(推荐!)
Expression exp = AviatorEvaluator.compile("a + b * 2");
Map<String, Object> env = new HashMap<>();
env.put("a", 10);
env.put("b", 20);
Object res = exp.execute(env);
System.out.println(res); // 50
}
}
⚠️ 重要:生产环境务必使用
compile()+execute(env)模式,避免重复解析!
3. 条件判断与三元运算
Expression exp = AviatorEvaluator.compile("score >= 90 ? '优秀' : (score >= 60 ? '及格' : '不及格')");
Map<String, Object> env = Map.of("score", 85);
System.out.println(exp.execute(env)); // 及格
4. 调用自定义函数(核心能力)
方式 1:Lambda 注册(推荐)
// 注册函数 max(a, b)
AviatorEvaluator.addFunction(new AbstractFunction() {
@Override
public String getName() { return "max"; }
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AvigatorObject arg2) {
Number a = FunctionUtils.getNumberValue(arg1, env);
Number b = FunctionUtils.getNumberValue(arg2, env);
return AviatorNumber.valueOf(Math.max(a.doubleValue(), b.doubleValue()));
}
});
// 使用
Expression exp = AviatorEvaluator.compile("max(x, y)");
Map<String, Object> env = Map.of("x", 10, "y", 20);
System.out.println(exp.execute(env)); // 20.0
方式 2:静态方法注册(Aviator 5.0+)
// 定义工具类
public class MathUtils {
@AviatorFunction("str_len") // 函数名
public static long strLen(String s) {
return s == null ? 0 : s.length();
}
}
// 自动扫描注册(需启用)
AviatorEvaluator.setOption(Options.FUNCTION_SCAN_PACKAGE, "com.yourpkg");
AviatorEvaluator.loadFunctions(); // 扫描带 @AviatorFunction 的类
// 使用
System.out.println(AviatorEvaluator.execute("str_len('hello')")); // 5
5. 操作复杂对象(POJO)
public class User {
private String name;
private int age;
// getter 必须 public!
public String getName() { return name; }
public int getAge() { return age; }
}
// 使用
User user = new User();
user.name = "Alice";
user.age = 25;
Map<String, Object> env = Map.of("user", user);
Object res = AviatorEvaluator.execute("user.age > 18 && user.name == 'Alice'", env);
System.out.println(res); // true
✅ Aviator 通过 getter 方法 访问对象属性(如
user.age→user.getAge())
三、高级用法
1. 内置函数库(无需注册)
// 字符串
AviatorEvaluator.execute("string.contains('hello', 'll')"); // true
AviatorEvaluator.execute("string.length('world')"); // 5
// 数学
AviatorEvaluator.execute("math.sqrt(16)"); // 4.0
AviatorEvaluator.execute("math.round(3.7)"); // 4
// 正则
AviatorEvaluator.execute("'abc123' =~ /\\d+/"); // true
// 集合
AviatorEvaluator.execute("count([1,2,3])"); // 3
AviatorEvaluator.execute("include([1,2,3], 2)"); // true
📌 完整内置函数列表:https://github.com/killme2008/aviator#built-in-functions
2. 集合与数组操作
List<Integer> scores = Arrays.asList(85, 90, 78);
Map<String, Object> env = Map.of("scores", scores);
// 求平均分
Object avg = AviatorEvaluator.execute("reduce(scores, 0, (acc, x) -> acc + x) / count(scores)", env);
System.out.println(avg); // 84.333...
// 过滤高分
Object highScores = AviatorEvaluator.execute("filter(scores, x -> x > 80)", env);
System.out.println(highScores); // [85, 90]
✅ 支持 Lambda 表达式(Aviator 5.0+)
3. 性能优化:表达式缓存
// 全局缓存(默认开启)
AviatorEvaluator.setOption(Options.EXPRESSION_CACHE_SIZE, 1000);
// 手动缓存
Map<String, Expression> cache = new ConcurrentHashMap<>();
String exprStr = "a + b";
Expression exp = cache.computeIfAbsent(exprStr, AviatorEvaluator::compile);
exp.execute(env);
4. 安全控制
// 禁用危险操作(默认已禁用)
AviatorEvaluator.setOption(Options.ALLOW_ACCESS_STATIC_FIELD, false);
AviatorEvaluator.setOption(Options.ALLOW_CLASS_LOADER, false);
// 仅允许白名单函数(通过 addFunction 控制)
四、典型应用场景
| 场景 | 表达示例 |
|---|---|
| 风控规则 | "user.riskLevel == 'HIGH' && order.amount > 10000" |
| 动态定价 | "basePrice * (1 + discountRate) - couponValue" |
| 游戏技能 | "player.hp -= enemy.attack * 1.5" |
| 数据过滤 | "include(user.tags, 'VIP') && user.balance > 100" |
| 配置化阈值 | "metric.value > config.threshold" |
五、与 QLExpress 对比
| 特性 | Aviator | QLExpress |
|---|---|---|
| 性能 | ⭐⭐⭐⭐⭐(数值计算更快) | ⭐⭐⭐⭐ |
| 语法简洁性 | 更接近数学表达式 | 支持 if/for 等语句 |
| 函数注册 | Lambda / 注解 | 反射注册 |
| 学习曲线 | 平缓 | 稍陡 |
| 社区活跃度 | 中等 | 阿里背书,较高 |
| 适用场景 | 高频计算、简单规则 | 复杂脚本逻辑 |
✅ 选择建议:
- 纯表达式计算(如公式、条件判断)→ Aviator
- 需要 if/for/while 等控制流 → QLExpress
六、最佳实践
- 始终编译表达式:使用
compile()而非execute(String) - 缓存 Expression 对象:避免重复编译
- 使用内置函数:优先用
math.sqrt()而非自定义 - POJO 提供 getter:确保属性可访问
- 异常处理:捕获
ExpressionRuntimeException
try {
exp.execute(env);
} catch (ExpressionRuntimeException e) {
log.error("Expression error: {}", e.getMessage());
}
七、完整示例:实时风控引擎
public class RiskEngine {
private final Map<String, Expression> ruleCache = new ConcurrentHashMap<>();
public boolean evaluate(String rule, Map<String, Object> context) {
Expression exp = ruleCache.computeIfAbsent(rule, AviatorEvaluator::compile);
try {
Object result = exp.execute(context);
return Boolean.TRUE.equals(result);
} catch (Exception e) {
log.warn("Rule evaluation failed: {}", rule, e);
return false; // 安全失败
}
}
}
// 使用
RiskEngine engine = new RiskEngine();
Map<String, Object> ctx = Map.of(
"ip", "192.168.1.100",
"amount", 15000,
"isVip", true
);
boolean blocked = engine.evaluate("amount > 10000 || !isVip", ctx);
总结
Aviator 是一款 极致性能、安全可控、语法简洁 的 Java 表达式引擎,特别适合高频、低延迟的规则计算场景。通过合理使用编译缓存、内置函数和自定义函数,可以高效实现业务逻辑的动态配置化。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19513153

浙公网安备 33010602011771号