Aviator 是一个轻量级且高性能的 Java 表达式求值引擎,专门用来动态计算和执行复杂的规则表达式,广泛应用于电商促销、风控评分等场景。本文将用最简单的语言介绍 Aviator 规则引擎的核心概念、组件设计及实战代码,帮助读者轻松理解和上手。
1. 什么是 Aviator 规则引擎?
-
定义:Aviator 是一个基于 Java 的表达式引擎,可以动态解析和执行字符串形式的表达式,支持数学运算、逻辑判断、自定义函数等。
-
优势:
- 轻量级,启动快,运行效率高
- 支持动态规则配置,无需重新编译和部署代码
- 方便业务人员配置复杂规则,减少开发工作量
2. 规则引擎的核心组成
规则通常由两部分组成:
- 条件(Condition) :规则触发的判断条件,比如“用户年龄 > 18”,“订单金额 >= 100”。
- 动作(Action) :当条件满足时执行的操作,比如“打折 10%”,“标记为高风险”。
3. 规则实体设计示例(Java)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Rule {
private String id; // 规则ID
private String expression; // 规则表达式(可直接写表达式,优先使用)
private List<Condition> conditions; // 条件列表
private Action action; // 条件满足时执行的动作
private Action fallbackAction; // 条件不满足时执行的动作
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Condition {
private String field; // 字段名,如 "age"
private String operator; // 操作符,如 ">", "=="
private List<String> value; // 比较值,如 ["18"]
private String customFunction; // 自定义函数名,如 "intersect"
private String logic; // 逻辑连接符,如 "&&", "||"
private boolean isValueQuoted = false; // 值是否带引号
private List<Condition> subConditions; // 子条件,支持嵌套
private boolean isBracketed; // 是否用括号包裹
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Action {
private String type; // 动作类型,如 "discount"
private Object target; // 动作目标,如折扣值 0.9
private Class<?> targetType; // 目标类型,如 Double.class
}
4. 规则表达式构建逻辑
规则表达式是由条件组成的逻辑表达式,示例代码演示如何将条件列表转换为 Aviator 可执行的表达式字符串:
public static String buildExpression(List<Condition> conditions) {
StringBuilder expressionBuilder = new StringBuilder();
for (int i = 0; i < conditions.size(); i++) {
Condition cond = conditions.get(i);
// 处理括号
if (cond.isBracketed()) expressionBuilder.append("(");
// 自定义函数优先使用
if (cond.getCustomFunction() != null && !cond.getCustomFunction().isEmpty()) {
String valueStr = cond.isValueQuoted() ? "'" + String.join(", ", cond.getValue()) + "'" : String.join(", ", cond.getValue());
expressionBuilder.append(cond.getCustomFunction())
.append("(")
.append(cond.getField())
.append(", ")
.append(valueStr)
.append(")");
} else {
// 普通条件拼接
String valueStr = cond.isValueQuoted() ? "'" + String.join(", ", cond.getValue()) + "'" : String.join(", ", cond.getValue());
expressionBuilder.append(cond.getField())
.append(" ")
.append(cond.getOperator())
.append(" ")
.append(valueStr);
}
if (cond.isBracketed()) expressionBuilder.append(")");
// 添加逻辑连接符
if (i < conditions.size() - 1 && cond.getLogic() != null) {
expressionBuilder.append(" ").append(cond.getLogic()).append(" ");
}
}
return expressionBuilder.toString();
}
5. Aviator表达式执行示例
5.1 简单表达式执行
Map<String, Object> env = new HashMap<>();
env.put("age", 20);
env.put("sumConsume", 3000);
env.put("vip", true);
String expression = "age >= 18 && sumConsume > 2000 && vip";
Boolean result = (Boolean) AviatorEvaluator.execute(expression, env);
System.out.println("规则判断结果:" + result); // 输出 true
5.2 自定义函数示例
// 自定义函数:判断两个字符串是否有交集
public class IntersectFunction extends AbstractFunction {
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
String str1 = FunctionUtils.getStringValue(arg1, env);
String str2 = FunctionUtils.getStringValue(arg2, env);
Set<String> set1 = new HashSet<>(Arrays.asList(str1.split(";")));
Set<String> set2 = new HashSet<>(Arrays.asList(str2.split(";")));
set1.retainAll(set2);
return AviatorBoolean.valueOf(!set1.isEmpty());
}
@Override
public String getName() {
return "intersect";
}
}
// 注册并使用
AviatorEvaluator.addFunction(new IntersectFunction());
Map<String, Object> env = new HashMap<>();
env.put("aircraftType", "NARROW;WIDE");
String expr = "intersect(aircraftType, 'NARROW;WIDE')";
Boolean res = (Boolean) AviatorEvaluator.execute(expr, env);
System.out.println("交集判断:" + res); // true
6. 复杂规则示例:多条件组合与匹配度计算
假设有如下规则条件:
- aircraftType 与 'NARROW;WIDE' 有交集
- firstClassVipPaxNum 与 '121;33' 有交集
- firstClassVipPaxNum > 1212
- airlineIcaoCode 以 'A320' 结尾
规则表达式:
String expr = "intersect(aircraftType, 'NARROW;WIDE') && " +
"intersect(firstClassVipPaxNum, '121;33') && " +
"firstClassVipPaxNum > 1212 && " +
"string.endsWith(airlineIcaoCode, 'A320')";
执行:
Map<String, Object> env = new HashMap<>();
env.put("aircraftType", "NARROW");
env.put("firstClassVipPaxNum", 1300);
env.put("airlineIcaoCode", "XXA320");
Boolean matched = (Boolean) AviatorEvaluator.execute(expr, env);
System.out.println("规则是否命中:" + matched); // true
匹配度计算(示例:至少3个条件满足):
int matchCount = 0;
if ((Boolean) AviatorEvaluator.execute("intersect(aircraftType, 'NARROW;WIDE')", env)) matchCount++;
if ((Boolean) AviatorEvaluator.execute("intersect(firstClassVipPaxNum, '121;33')", env)) matchCount++;
if ((Boolean) AviatorEvaluator.execute("firstClassVipPaxNum > 1212", env)) matchCount++;
if ((Boolean) AviatorEvaluator.execute("string.endsWith(airlineIcaoCode, 'A320')", env)) matchCount++;
int requiredMatch = 3;
int result = matchCount >= requiredMatch ? matchCount : -1;
System.out.println("匹配度:" + result); // 4
7. 总结与建议
- Aviator 规则引擎能让业务规则动态化,减少代码变更和发布成本。
- 通过设计统一的规则实体(Rule、Condition、Action),可以灵活构建复杂规则。
- 自定义函数扩展了规则表达式的能力,满足业务多样需求。
- 结合表达式构建和执行,支持批量规则计算和匹配度评估,适合电商促销、风控等场景。
8. 参考依赖(Maven)
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.3.0</version> <!-- 请根据实际情况选择最新稳定版本 -->
</dependency>
通过以上介绍和示例代码,您可以快速理解 Aviator 规则引擎的基础知识及其在实际项目中的应用,轻松实现动态规则管理和执行。