Aviator规则引擎基础知识与实战解析

2,997 阅读4分钟

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 规则引擎的基础知识及其在实际项目中的应用,轻松实现动态规则管理和执行。