Aviator表达式引擎详解:从入门到实战
前言
Aviator 是一个高性能、轻量级的 Java 表达式求值引擎,主要用于各种表达式的动态求值。它支持大部分运算操作符,支持函数调用和自定义函数,支持正则表达式匹配,支持lambda表达式等。Aviator 被广泛应用于规则引擎、动态脚本执行、配置管理等场景。本文将深入讲解 Aviator 的核心概念、使用方法和实战应用。
一、Aviator 概述
1.1 什么是 Aviator
Aviator 是由国内开发者开源的表达式求值引擎,具有以下特点:
Aviator 特性
┌─────────────────────────────────────────┐
│ ✓ 轻量级:核心库不到 500KB │
│ ✓ 高性能:编译执行,性能接近 Java 代码 │
│ ✓ 功能丰富:支持丰富的运算符和函数 │
│ ✓ 可扩展:支持自定义函数和操作符 │
│ ✓ 安全可控:可限制表达式执行权限 │
└─────────────────────────────────────────┘
1.2 应用场景
Aviator 典型应用场景
┌─────────────────────────────────────────┐
│ 1. 规则引擎 │
│ - 业务规则动态配置 │
│ - 价格计算 │
│ - 权限判断 │
│ │
│ 2. 动态计算 │
│ - 公式计算 │
│ - 统计分析 │
│ - 数据转换 │
│ │
│ 3. 配置管理 │
│ - 动态配置解析 │
│ - 条件判断 │
│ - 参数计算 │
└─────────────────────────────────────────┘
1.3 核心架构
Aviator 执行流程
┌─────────────────────────────────────────┐
│ 表达式字符串 │
│ ↓ │
│ ┌──────────────┐ │
│ │ 词法分析器 │ │
│ └──────┬───────┘ │
│ ↓ │
│ ┌──────────────┐ │
│ │ 语法分析器 │ │
│ └──────┬───────┘ │
│ ↓ │
│ ┌──────────────┐ │
│ │ 编译器 │ → 生成字节码 │
│ └──────┬───────┘ │
│ ↓ │
│ ┌──────────────┐ │
│ │ 执行引擎 │ → 执行并返回结果 │
│ └──────────────┘ │
└─────────────────────────────────────────┘
二、快速开始
2.1 Maven 依赖
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.3.3</version>
</dependency>
2.2 基础示例
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
/**
* Aviator 基础示例
*/
public class AviatorBasicDemo {
public static void main(String[] args) {
// 1. 最简单的表达式求值
Long result = (Long) AviatorEvaluator.execute("1 + 2 + 3");
System.out.println("1 + 2 + 3 = " + result); // 6
// 2. 使用变量
Map<String, Object> env = new HashMap<>();
env.put("x", 10);
env.put("y", 20);
Long sum = (Long) AviatorEvaluator.execute("x + y", env);
System.out.println("x + y = " + sum); // 30
// 3. 字符串操作
env.put("name", "张三");
String greeting = (String) AviatorEvaluator.execute("'Hello, ' + name", env);
System.out.println(greeting); // Hello, 张三
// 4. 编译后多次执行(性能更好)
Expression compiled = AviatorEvaluator.compile("a * b + c");
env.clear();
env.put("a", 2);
env.put("b", 3);
env.put("c", 4);
System.out.println("2 * 3 + 4 = " + compiled.execute(env)); // 10
env.put("a", 5);
env.put("b", 6);
env.put("c", 7);
System.out.println("5 * 6 + 7 = " + compiled.execute(env)); // 37
}
}
2.3 数据类型
/**
* Aviator 支持的数据类型
*/
public class DataTypeDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
// 整数
env.put("intValue", 100);
System.out.println(AviatorEvaluator.execute("intValue + 50", env)); // 150
// 浮点数
env.put("doubleValue", 3.14);
System.out.println(AviatorEvaluator.execute("doubleValue * 2", env)); // 6.28
// 字符串
env.put("str", "Hello");
System.out.println(AviatorEvaluator.execute("str + ' World'", env)); // Hello World
// 布尔值
env.put("flag", true);
System.out.println(AviatorEvaluator.execute("flag && true", env)); // true
// nil (null)
env.put("nullValue", null);
System.out.println(AviatorEvaluator.execute("nullValue == nil", env)); // true
// 正则表达式
env.put("email", "test@example.com");
Boolean matches = (Boolean) AviatorEvaluator.execute(
"email =~ /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z]+$/", env);
System.out.println("Email格式正确: " + matches); // true
// BigInteger 和 BigDecimal
env.put("bigInt", new BigInteger("123456789012345678901234567890"));
env.put("bigDec", new BigDecimal("123.456"));
System.out.println(AviatorEvaluator.execute("bigInt + 1", env));
System.out.println(AviatorEvaluator.execute("bigDec * 2", env));
}
}
三、运算符详解
3.1 算术运算符
/**
* 算术运算符示例
*/
public class ArithmeticOperatorDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("a", 10);
env.put("b", 3);
// 加法
System.out.println("a + b = " + AviatorEvaluator.execute("a + b", env)); // 13
// 减法
System.out.println("a - b = " + AviatorEvaluator.execute("a - b", env)); // 7
// 乘法
System.out.println("a * b = " + AviatorEvaluator.execute("a * b", env)); // 30
// 除法
System.out.println("a / b = " + AviatorEvaluator.execute("a / b", env)); // 3
// 取模
System.out.println("a % b = " + AviatorEvaluator.execute("a % b", env)); // 1
// 负数
System.out.println("-a = " + AviatorEvaluator.execute("-a", env)); // -10
// 复杂表达式
System.out.println("(a + b) * 2 = " +
AviatorEvaluator.execute("(a + b) * 2", env)); // 26
}
}
3.2 比较运算符
/**
* 比较运算符示例
*/
public class ComparisonOperatorDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("x", 10);
env.put("y", 20);
env.put("name", "张三");
// 等于
System.out.println("x == 10: " + AviatorEvaluator.execute("x == 10", env)); // true
// 不等于
System.out.println("x != y: " + AviatorEvaluator.execute("x != y", env)); // true
// 大于
System.out.println("y > x: " + AviatorEvaluator.execute("y > x", env)); // true
// 小于
System.out.println("x < y: " + AviatorEvaluator.execute("x < y", env)); // true
// 大于等于
System.out.println("x >= 10: " + AviatorEvaluator.execute("x >= 10", env)); // true
// 小于等于
System.out.println("y <= 20: " + AviatorEvaluator.execute("y <= 20", env)); // true
// 字符串比较
System.out.println("name == '张三': " +
AviatorEvaluator.execute("name == '张三'", env)); // true
}
}
3.3 逻辑运算符
/**
* 逻辑运算符示例
*/
public class LogicalOperatorDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("a", true);
env.put("b", false);
env.put("age", 25);
// 逻辑与
System.out.println("a && b: " + AviatorEvaluator.execute("a && b", env)); // false
// 逻辑或
System.out.println("a || b: " + AviatorEvaluator.execute("a || b", env)); // true
// 逻辑非
System.out.println("!a: " + AviatorEvaluator.execute("!a", env)); // false
// 复合条件
System.out.println("age >= 18 && age <= 60: " +
AviatorEvaluator.execute("age >= 18 && age <= 60", env)); // true
// 短路运算
System.out.println("b || (age > 18): " +
AviatorEvaluator.execute("b || (age > 18)", env)); // true
}
}
3.4 三元运算符
/**
* 三元运算符示例
*/
public class TernaryOperatorDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("score", 85);
env.put("age", 17);
// 基本三元运算
String result = (String) AviatorEvaluator.execute(
"score >= 60 ? '及格' : '不及格'", env);
System.out.println("成绩: " + result); // 及格
// 嵌套三元运算
String grade = (String) AviatorEvaluator.execute(
"score >= 90 ? '优秀' : (score >= 80 ? '良好' : (score >= 60 ? '及格' : '不及格'))",
env);
System.out.println("等级: " + grade); // 良好
// 条件判断
String status = (String) AviatorEvaluator.execute(
"age >= 18 ? '成年' : '未成年'", env);
System.out.println("状态: " + status); // 未成年
}
}
四、内置函数
4.1 数学函数
/**
* 数学函数示例
*/
public class MathFunctionDemo {
public static void main(String[] args) {
// abs - 绝对值
System.out.println("abs(-10) = " + AviatorEvaluator.execute("math.abs(-10)")); // 10
// sqrt - 平方根
System.out.println("sqrt(16) = " + AviatorEvaluator.execute("math.sqrt(16)")); // 4.0
// pow - 幂运算
System.out.println("pow(2, 3) = " + AviatorEvaluator.execute("math.pow(2, 3)")); // 8.0
// round - 四舍五入
System.out.println("round(3.6) = " + AviatorEvaluator.execute("math.round(3.6)")); // 4
// floor - 向下取整
System.out.println("floor(3.9) = " + AviatorEvaluator.execute("math.floor(3.9)")); // 3
// ceil - 向上取整
System.out.println("ceil(3.1) = " + AviatorEvaluator.execute("math.ceil(3.1)")); // 4
// max/min - 最大最小值
System.out.println("max(10, 20, 5) = " +
AviatorEvaluator.execute("math.max(10, 20, 5)")); // 20
System.out.println("min(10, 20, 5) = " +
AviatorEvaluator.execute("math.min(10, 20, 5)")); // 5
// log - 对数
System.out.println("log(10) = " + AviatorEvaluator.execute("math.log(10)"));
// sin/cos/tan - 三角函数
System.out.println("sin(0) = " + AviatorEvaluator.execute("math.sin(0)")); // 0.0
}
}
4.2 字符串函数
/**
* 字符串函数示例
*/
public class StringFunctionDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("str", "Hello World");
env.put("name", " 张三 ");
// string.length - 字符串长度
System.out.println("length: " +
AviatorEvaluator.execute("string.length(str)", env)); // 11
// string.substring - 子串
System.out.println("substring: " +
AviatorEvaluator.execute("string.substring(str, 0, 5)", env)); // Hello
// string.startsWith - 开始判断
System.out.println("startsWith: " +
AviatorEvaluator.execute("string.startsWith(str, 'Hello')", env)); // true
// string.endsWith - 结束判断
System.out.println("endsWith: " +
AviatorEvaluator.execute("string.endsWith(str, 'World')", env)); // true
// string.indexOf - 查找位置
System.out.println("indexOf: " +
AviatorEvaluator.execute("string.indexOf(str, 'World')", env)); // 6
// string.contains - 包含判断
System.out.println("contains: " +
AviatorEvaluator.execute("string.contains(str, 'llo')", env)); // true
// string.toLowerCase - 转小写
System.out.println("toLowerCase: " +
AviatorEvaluator.execute("string.toLowerCase(str)", env)); // hello world
// string.toUpperCase - 转大写
System.out.println("toUpperCase: " +
AviatorEvaluator.execute("string.toUpperCase(str)", env)); // HELLO WORLD
// string.trim - 去除空格
System.out.println("trim: [" +
AviatorEvaluator.execute("string.trim(name)", env) + "]"); // [张三]
// string.replace - 替换
System.out.println("replace: " +
AviatorEvaluator.execute("string.replace(str, 'World', 'Java')", env)); // Hello Java
// string.split - 分割
String[] parts = (String[]) AviatorEvaluator.execute("string.split(str, ' ')", env);
System.out.println("split: " + Arrays.toString(parts)); // [Hello, World]
}
}
4.3 集合函数
/**
* 集合函数示例
*/
public class CollectionFunctionDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("list", Arrays.asList(1, 2, 3, 4, 5));
env.put("map", new HashMap<String, Object>() {{
put("name", "张三");
put("age", 25);
}});
// count - 集合大小
System.out.println("count: " +
AviatorEvaluator.execute("count(list)", env)); // 5
// include - 包含判断
System.out.println("include: " +
AviatorEvaluator.execute("include(list, 3)", env)); // true
// seq.get - 获取元素
System.out.println("get: " +
AviatorEvaluator.execute("seq.get(list, 0)", env)); // 1
// seq.map - 映射转换
Expression mapExpr = AviatorEvaluator.compile("seq.map(list, lambda(x) -> x * 2 end)");
Object result = mapExpr.execute(env);
System.out.println("map: " + result); // [2, 4, 6, 8, 10]
// seq.filter - 过滤
Expression filterExpr = AviatorEvaluator.compile(
"seq.filter(list, lambda(x) -> x > 2 end)");
System.out.println("filter: " + filterExpr.execute(env)); // [3, 4, 5]
// seq.reduce - 归约
Expression reduceExpr = AviatorEvaluator.compile(
"seq.reduce(list, lambda(sum, x) -> sum + x end, 0)");
System.out.println("reduce: " + reduceExpr.execute(env)); // 15
// map.keys - 获取所有键
System.out.println("keys: " +
AviatorEvaluator.execute("seq.map(map, lambda(k,v) -> k end)", env));
}
}
4.4 日期时间函数
/**
* 日期时间函数示例
*/
public class DateFunctionDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
env.put("now", new Date());
env.put("dateStr", "2024-01-15");
// date.now - 当前时间戳
System.out.println("now: " + AviatorEvaluator.execute("date.now()"));
// date.format - 格式化日期
System.out.println("format: " +
AviatorEvaluator.execute("date.format(now, 'yyyy-MM-dd HH:mm:ss')", env));
// date.parse - 解析日期字符串
Date parsed = (Date) AviatorEvaluator.execute(
"date.parse(dateStr, 'yyyy-MM-dd')", env);
System.out.println("parsed: " + parsed);
// date.year/month/day - 提取日期部分
System.out.println("year: " +
AviatorEvaluator.execute("date.year(now)", env));
System.out.println("month: " +
AviatorEvaluator.execute("date.month(now)", env));
System.out.println("day: " +
AviatorEvaluator.execute("date.day(now)", env));
// 日期比较
env.put("date1", new Date());
env.put("date2", new Date(System.currentTimeMillis() - 86400000)); // 昨天
System.out.println("date1 > date2: " +
AviatorEvaluator.execute("date1 > date2", env)); // true
}
}
五、自定义函数
5.1 基础自定义函数
/**
* 自定义函数 - 实现 AviatorFunction 接口
*/
public class AddFunction extends AbstractFunction {
@Override
public String getName() {
return "add";
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
Number num1 = FunctionUtils.getNumberValue(arg1, env);
Number num2 = FunctionUtils.getNumberValue(arg2, env);
return AviatorDouble.valueOf(num1.doubleValue() + num2.doubleValue());
}
}
/**
* 多参数自定义函数
*/
public class MaxFunction extends AbstractVariadicFunction {
@Override
public String getName() {
return "myMax";
}
@Override
public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
if (args == null || args.length == 0) {
throw new IllegalArgumentException("至少需要一个参数");
}
double max = Double.MIN_VALUE;
for (AviatorObject arg : args) {
Number num = FunctionUtils.getNumberValue(arg, env);
max = Math.max(max, num.doubleValue());
}
return AviatorDouble.valueOf(max);
}
}
/**
* 使用自定义函数
*/
public class CustomFunctionDemo {
public static void main(String[] args) {
// 注册自定义函数
AviatorEvaluator.addFunction(new AddFunction());
AviatorEvaluator.addFunction(new MaxFunction());
// 使用自定义函数
Map<String, Object> env = new HashMap<>();
env.put("a", 10);
env.put("b", 20);
System.out.println("add(a, b) = " +
AviatorEvaluator.execute("add(a, b)", env)); // 30
System.out.println("myMax(1, 5, 3, 9, 2) = " +
AviatorEvaluator.execute("myMax(1, 5, 3, 9, 2)")); // 9
}
}
5.2 复杂自定义函数
/**
* 字符串处理函数
*/
public class StringUtilsFunction extends AbstractVariadicFunction {
@Override
public String getName() {
return "strUtil";
}
@Override
public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
if (args.length < 2) {
throw new IllegalArgumentException("至少需要2个参数:操作类型和字符串");
}
String operation = FunctionUtils.getStringValue(args[0], env);
String str = FunctionUtils.getStringValue(args[1], env);
switch (operation) {
case "reverse":
return new AviatorString(new StringBuilder(str).reverse().toString());
case "capitalize":
return new AviatorString(
str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase());
case "repeat":
if (args.length < 3) {
throw new IllegalArgumentException("repeat操作需要重复次数参数");
}
int times = FunctionUtils.getNumberValue(args[2], env).intValue();
return new AviatorString(str.repeat(times));
default:
throw new IllegalArgumentException("不支持的操作: " + operation);
}
}
}
/**
* 使用示例
*/
public class ComplexFunctionDemo {
public static void main(String[] args) {
AviatorEvaluator.addFunction(new StringUtilsFunction());
Map<String, Object> env = new HashMap<>();
env.put("text", "hello");
System.out.println("reverse: " +
AviatorEvaluator.execute("strUtil('reverse', text)", env)); // olleh
System.out.println("capitalize: " +
AviatorEvaluator.execute("strUtil('capitalize', text)", env)); // Hello
System.out.println("repeat: " +
AviatorEvaluator.execute("strUtil('repeat', text, 3)", env)); // hellohellohello
}
}
六、Lambda 表达式
6.1 Lambda 基础
/**
* Lambda 表达式示例
*/
public class LambdaDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
// 简单 lambda
Expression expr1 = AviatorEvaluator.compile("lambda(x) -> x * 2 end");
env.put("num", 5);
System.out.println(expr1.execute(env)); // 10
// 多参数 lambda
Expression expr2 = AviatorEvaluator.compile("lambda(x, y) -> x + y end");
System.out.println(expr2.execute(env));
// lambda 作为参数
env.put("list", Arrays.asList(1, 2, 3, 4, 5));
Expression expr3 = AviatorEvaluator.compile(
"seq.map(list, lambda(x) -> x * x end)");
System.out.println(expr3.execute(env)); // [1, 4, 9, 16, 25]
// filter 过滤偶数
Expression expr4 = AviatorEvaluator.compile(
"seq.filter(list, lambda(x) -> x % 2 == 0 end)");
System.out.println(expr4.execute(env)); // [2, 4]
// reduce 累加
Expression expr5 = AviatorEvaluator.compile(
"seq.reduce(list, lambda(sum, x) -> sum + x end, 0)");
System.out.println(expr5.execute(env)); // 15
}
}
6.2 复杂 Lambda 应用
/**
* 复杂 Lambda 应用
*/
public class AdvancedLambdaDemo {
public static void main(String[] args) {
Map<String, Object> env = new HashMap<>();
// 对象列表处理
List<Map<String, Object>> users = Arrays.asList(
new HashMap<String, Object>() {{
put("name", "张三");
put("age", 25);
put("salary", 8000);
}},
new HashMap<String, Object>() {{
put("name", "李四");
put("age", 30);
put("salary", 12000);
}},
new HashMap<String, Object>() {{
put("name", "王五");
put("age", 28);
put("salary", 10000);
}}
);
env.put("users", users);
// 筛选年龄大于 25 的用户
Expression filterExpr = AviatorEvaluator.compile(
"seq.filter(users, lambda(u) -> u.age > 25 end)");
System.out.println("年龄>25: " + filterExpr.execute(env));
// 提取所有用户名
Expression mapExpr = AviatorEvaluator.compile(
"seq.map(users, lambda(u) -> u.name end)");
System.out.println("所有姓名: " + mapExpr.execute(env)); // [张三, 李四, 王五]
// 计算总工资
Expression reduceExpr = AviatorEvaluator.compile(
"seq.reduce(users, lambda(sum, u) -> sum + u.salary end, 0)");
System.out.println("总工资: " + reduceExpr.execute(env)); // 30000
// 排序(使用 sort 函数)
Expression sortExpr = AviatorEvaluator.compile(
"seq.sort(users, lambda(u1, u2) -> u1.age - u2.age end)");
System.out.println("按年龄排序: " + sortExpr.execute(env));
// 链式操作
Expression chainExpr = AviatorEvaluator.compile(
"seq.reduce(" +
" seq.map(" +
" seq.filter(users, lambda(u) -> u.age > 25 end)," +
" lambda(u) -> u.salary end" +
" )," +
" lambda(sum, s) -> sum + s end," +
" 0" +
")");
System.out.println("年龄>25的总工资: " + chainExpr.execute(env)); // 22000
}
}
七、实战案例
7.1 案例1:动态规则引擎
/**
* 规则定义
*/
@Data
public class Rule {
private String id;
private String name;
private String condition; // 条件表达式
private String action; // 动作表达式
private Integer priority; // 优先级
private Boolean enabled; // 是否启用
}
/**
* 规则引擎
*/
@Service
public class RuleEngine {
private final List<Rule> rules = new CopyOnWriteArrayList<>();
private final Map<String, Expression> compiledRules = new ConcurrentHashMap<>();
/**
* 添加规则
*/
public void addRule(Rule rule) {
if (rule.getEnabled()) {
rules.add(rule);
// 预编译规则
compiledRules.put(rule.getId(), AviatorEvaluator.compile(rule.getCondition()));
}
}
/**
* 执行规则
*/
public List<String> execute(Map<String, Object> context) {
List<String> firedRules = new ArrayList<>();
// 按优先级排序
rules.stream()
.sorted(Comparator.comparing(Rule::getPriority).reversed())
.forEach(rule -> {
Expression conditionExpr = compiledRules.get(rule.getId());
if (conditionExpr != null) {
try {
Boolean result = (Boolean) conditionExpr.execute(context);
if (Boolean.TRUE.equals(result)) {
// 条件满足,执行动作
executeAction(rule, context);
firedRules.add(rule.getId());
}
} catch (Exception e) {
System.err.println("规则执行失败: " + rule.getId() + ", " + e.getMessage());
}
}
});
return firedRules;
}
/**
* 执行动作
*/
private void executeAction(Rule rule, Map<String, Object> context) {
if (rule.getAction() != null && !rule.getAction().isEmpty()) {
AviatorEvaluator.execute(rule.getAction(), context);
}
}
/**
* 移除规则
*/
public void removeRule(String ruleId) {
rules.removeIf(r -> r.getId().equals(ruleId));
compiledRules.remove(ruleId);
}
}
/**
* 规则引擎使用示例
*/
public class RuleEngineDemo {
public static void main(String[] args) {
RuleEngine engine = new RuleEngine();
// 定义规则1:VIP折扣
Rule rule1 = new Rule();
rule1.setId("RULE001");
rule1.setName("VIP用户折扣");
rule1.setCondition("userLevel == 'VIP' && orderAmount > 1000");
rule1.setAction("discount = 0.8");
rule1.setPriority(10);
rule1.setEnabled(true);
engine.addRule(rule1);
// 定义规则2:新用户优惠
Rule rule2 = new Rule();
rule2.setId("RULE002");
rule2.setName("新用户首单优惠");
rule2.setCondition("isNewUser == true && orderCount == 1");
rule2.setAction("discount = 0.9");
rule2.setPriority(5);
rule2.setEnabled(true);
engine.addRule(rule2);
// 定义规则3:满减活动
Rule rule3 = new Rule();
rule3.setId("RULE003");
rule3.setName("满500减50");
rule3.setCondition("orderAmount >= 500");
rule3.setAction("couponAmount = 50");
rule3.setPriority(1);
rule3.setEnabled(true);
engine.addRule(rule3);
// 测试场景1:VIP用户下单
Map<String, Object> context1 = new HashMap<>();
context1.put("userLevel", "VIP");
context1.put("orderAmount", 1500);
context1.put("isNewUser", false);
context1.put("orderCount", 10);
context1.put("discount", 1.0);
context1.put("couponAmount", 0);
List<String> fired1 = engine.execute(context1);
System.out.println("触发规则: " + fired1);
System.out.println("折扣: " + context1.get("discount"));
System.out.println("优惠券: " + context1.get("couponAmount"));
System.out.println("\n---\n");
// 测试场景2:新用户首单
Map<String, Object> context2 = new HashMap<>();
context2.put("userLevel", "NORMAL");
context2.put("orderAmount", 600);
context2.put("isNewUser", true);
context2.put("orderCount", 1);
context2.put("discount", 1.0);
context2.put("couponAmount", 0);
List<String> fired2 = engine.execute(context2);
System.out.println("触发规则: " + fired2);
System.out.println("折扣: " + context2.get("discount"));
System.out.println("优惠券: " + context2.get("couponAmount"));
}
}
7.2 案例2:动态公式计算
/**
* 公式定义
*/
@Data
public class Formula {
private String id;
private String name;
private String expression;
private String description;
}
/**
* 公式计算引擎
*/
@Service
public class FormulaEngine {
private final Map<String, Expression> compiledFormulas = new ConcurrentHashMap<>();
/**
* 注册公式
*/
public void register(Formula formula) {
try {
Expression compiled = AviatorEvaluator.compile(formula.getExpression());
compiledFormulas.put(formula.getId(), compiled);
} catch (Exception e) {
throw new RuntimeException("公式编译失败: " + formula.getId(), e);
}
}
/**
* 计算公式
*/
public Object calculate(String formulaId, Map<String, Object> variables) {
Expression expr = compiledFormulas.get(formulaId);
if (expr == null) {
throw new IllegalArgumentException("公式不存在: " + formulaId);
}
return expr.execute(variables);
}
/**
* 批量计算
*/
public Map<String, Object> batchCalculate(List<String> formulaIds,
Map<String, Object> variables) {
Map<String, Object> results = new HashMap<>();
for (String formulaId : formulaIds) {
try {
Object result = calculate(formulaId, variables);
results.put(formulaId, result);
} catch (Exception e) {
results.put(formulaId, "ERROR: " + e.getMessage());
}
}
return results;
}
}
/**
* 公式计算示例
*/
public class FormulaDemo {
public static void main(String[] args) {
FormulaEngine engine = new FormulaEngine();
// 注册公式
Formula formula1 = new Formula();
formula1.setId("BMI");
formula1.setName("身体质量指数");
formula1.setExpression("weight / (height * height)");
formula1.setDescription("BMI = 体重(kg) / 身高²(m)");
engine.register(formula1);
Formula formula2 = new Formula();
formula2.setId("COMPOUND_INTEREST");
formula2.setName("复利计算");
formula2.setExpression("principal * math.pow(1 + rate, years)");
formula2.setDescription("本金 × (1 + 利率)^年数");
engine.register(formula2);
Formula formula3 = new Formula();
formula3.setId("ORDER_TOTAL");
formula3.setName("订单总价");
formula3.setExpression("price * quantity * (1 - discount) + shipping");
formula3.setDescription("(单价 × 数量 × 折扣) + 运费");
engine.register(formula3);
// 计算 BMI
Map<String, Object> bmiVars = new HashMap<>();
bmiVars.put("weight", 70.0); // 70kg
bmiVars.put("height", 1.75); // 1.75m
Object bmi = engine.calculate("BMI", bmiVars);
System.out.println("BMI: " + String.format("%.2f", bmi));
// 计算复利
Map<String, Object> interestVars = new HashMap<>();
interestVars.put("principal", 10000); // 本金 10000
interestVars.put("rate", 0.05); // 年利率 5%
interestVars.put("years", 10); // 10年
Object finalAmount = engine.calculate("COMPOUND_INTEREST", interestVars);
System.out.println("10年后本息: " + String.format("%.2f", finalAmount));
// 计算订单总价
Map<String, Object> orderVars = new HashMap<>();
orderVars.put("price", 99.99);
orderVars.put("quantity", 3);
orderVars.put("discount", 0.1); // 9折
orderVars.put("shipping", 10.0);
Object total = engine.calculate("ORDER_TOTAL", orderVars);
System.out.println("订单总价: " + String.format("%.2f", total));
// 批量计算
Map<String, Object> vars = new HashMap<>();
vars.putAll(bmiVars);
vars.putAll(interestVars);
vars.putAll(orderVars);
Map<String, Object> results = engine.batchCalculate(
Arrays.asList("BMI", "COMPOUND_INTEREST", "ORDER_TOTAL"), vars);
System.out.println("\n批量计算结果:");
results.forEach((k, v) -> System.out.println(k + ": " + v));
}
}
7.3 案例3:配置表达式解析
/**
* 配置管理器
*/
@Component
public class ConfigManager {
@Autowired
private Environment environment;
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>();
/**
* 获取配置值(支持表达式)
*/
public Object getConfig(String key, Map<String, Object> context) {
String value = environment.getProperty(key);
if (value == null) {
return null;
}
// 判断是否为表达式
if (value.startsWith("${") && value.endsWith("}")) {
String expression = value.substring(2, value.length() - 1);
return evaluateExpression(expression, context);
}
return value;
}
/**
* 执行表达式
*/
private Object evaluateExpression(String expression, Map<String, Object> context) {
Expression compiled = expressionCache.computeIfAbsent(
expression,
expr -> AviatorEvaluator.compile(expr)
);
// 添加系统属性和环境变量
Map<String, Object> env = new HashMap<>(context);
env.put("sys", System.getProperties());
env.put("env", System.getenv());
return compiled.execute(env);
}
/**
* 批量解析配置
*/
public Map<String, Object> parseConfig(List<String> keys, Map<String, Object> context) {
return keys.stream()
.collect(Collectors.toMap(
key -> key,
key -> getConfig(key, context)
));
}
}
/**
* 配置示例
*/
/*
application.properties:
# 简单配置
app.name=MyApp
app.version=1.0.0
# 表达式配置
app.max-threads=${math.max(cores * 2, 4)}
app.timeout=${env == 'prod' ? 30000 : 5000}
app.log-level=${env == 'prod' ? 'WARN' : 'DEBUG'}
app.cache-size=${math.min(memory / 10, 1024)}
*/
@SpringBootTest
class ConfigManagerTest {
@Autowired
private ConfigManager configManager;
@Test
void testConfigExpression() {
Map<String, Object> context = new HashMap<>();
context.put("cores", Runtime.getRuntime().availableProcessors());
context.put("env", "dev");
context.put("memory", 8192);
// 解析表达式配置
Object maxThreads = configManager.getConfig("app.max-threads", context);
Object timeout = configManager.getConfig("app.timeout", context);
Object logLevel = configManager.getConfig("app.log-level", context);
System.out.println("Max Threads: " + maxThreads);
System.out.println("Timeout: " + timeout);
System.out.println("Log Level: " + logLevel);
}
}
八、性能优化
8.1 表达式编译与缓存
/**
* 表达式缓存管理
*/
public class ExpressionCache {
private static final Cache<String, Expression> CACHE = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterAccess(1, TimeUnit.HOURS)
.recordStats()
.build();
/**
* 获取或编译表达式
*/
public static Expression getOrCompile(String expression) {
try {
return CACHE.get(expression, () -> AviatorEvaluator.compile(expression));
} catch (ExecutionException e) {
throw new RuntimeException("表达式编译失败: " + expression, e);
}
}
/**
* 清除缓存
*/
public static void clear() {
CACHE.invalidateAll();
}
/**
* 获取缓存统计
*/
public static CacheStats getStats() {
return CACHE.stats();
}
}
/**
* 性能测试
*/
public class PerformanceTest {
public static void main(String[] args) {
String expression = "x * 2 + y * 3 + z * 4";
int iterations = 100000;
// 测试1:每次都解释执行
long start1 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
Map<String, Object> env = new HashMap<>();
env.put("x", i);
env.put("y", i + 1);
env.put("z", i + 2);
AviatorEvaluator.execute(expression, env);
}
long time1 = System.currentTimeMillis() - start1;
System.out.println("解释执行: " + time1 + "ms");
// 测试2:编译一次,多次执行
long start2 = System.currentTimeMillis();
Expression compiled = AviatorEvaluator.compile(expression);
for (int i = 0; i < iterations; i++) {
Map<String, Object> env = new HashMap<>();
env.put("x", i);
env.put("y", i + 1);
env.put("z", i + 2);
compiled.execute(env);
}
long time2 = System.currentTimeMillis() - start2;
System.out.println("编译执行: " + time2 + "ms");
System.out.println("性能提升: " + (time1 - time2) + "ms (" +
String.format("%.1f", (time1 - time2) * 100.0 / time1) + "%)");
}
}
8.2 最佳实践
/**
* Aviator 最佳实践
*/
public class BestPractices {
// ✓ 推荐:编译后重用
private static final Expression COMPILED_EXPR =
AviatorEvaluator.compile("x + y");
public void goodExample() {
Map<String, Object> env = new HashMap<>();
env.put("x", 10);
env.put("y", 20);
// 多次执行同一个编译后的表达式
COMPILED_EXPR.execute(env);
}
// ✗ 不推荐:每次都执行字符串
public void badExample() {
Map<String, Object> env = new HashMap<>();
env.put("x", 10);
env.put("y", 20);
// 每次都要解析和编译
AviatorEvaluator.execute("x + y", env);
}
// ✓ 推荐:使用缓存
private final Map<String, Expression> cache = new ConcurrentHashMap<>();
public Object evaluateWithCache(String expr, Map<String, Object> env) {
Expression compiled = cache.computeIfAbsent(
expr,
e -> AviatorEvaluator.compile(e)
);
return compiled.execute(env);
}
// ✓ 推荐:异常处理
public Object safeEvaluate(String expr, Map<String, Object> env) {
try {
Expression compiled = AviatorEvaluator.compile(expr);
return compiled.execute(env);
} catch (ExpressionSyntaxErrorException e) {
System.err.println("表达式语法错误: " + e.getMessage());
return null;
} catch (ExpressionRuntimeException e) {
System.err.println("表达式执行错误: " + e.getMessage());
return null;
}
}
}
九、总结
核心知识点回顾
Aviator 表达式引擎核心要点
│
├── 基础概念
│ ├── 轻量级表达式引擎
│ ├── 编译执行模式
│ └── 丰富的数据类型支持
│
├── 运算符
│ ├── 算术运算符
│ ├── 比较运算符
│ ├── 逻辑运算符
│ └── 三元运算符
│
├── 内置函数
│ ├── 数学函数
│ ├── 字符串函数
│ ├── 集合函数
│ └── 日期时间函数
│
├── 高级特性
│ ├── 自定义函数
│ ├── Lambda 表达式
│ └── 正则表达式
│
├── 实战应用
│ ├── 动态规则引擎
│ ├── 公式计算引擎
│ └── 配置表达式解析
│
└── 性能优化
├── 表达式编译
├── 结果缓存
└── 最佳实践
Aviator 是一个功能强大、性能优异的表达式引擎,特别适合需要动态表达式求值的场景。通过合理使用编译缓存、自定义函数等特性,可以构建高性能的规则引擎和计算引擎。