> 技术文档 > Google Aviator:轻量级Java公式引擎完全指南

Google Aviator:轻量级Java公式引擎完全指南


Google Aviator:轻量级Java公式引擎完全指南

文章目录

  • Google Aviator:轻量级Java公式引擎完全指南
    • Aviator简介
      • 核心优势
      • 典型应用场景
      • 核心特性详解
      • 自定义函数参考表
    • Spring Boot集成
      • 1. Maven依赖
      • 2. Expression类结构
      • 3. 表达式构建方法
      • 4.类型转换类
      • 5.自定义函数
        • 1.特殊字符函数
        • 2.位运算函数
        • 3.数组运算函数
      • 6. 表达式求值方法
      • 7.完整示例
    • 使用示例
      • 1. 基本算术运算
      • 2. 数组操作
      • 3. 位操作
    • 高级特性
      • 1. 类型声明
      • 2. 特殊变量名处理
    • 最佳实践
      • 1. 性能优化
      • 2. 安全建议
      • 3. 异常处理
    • 常见问题
      • 1. 变量未定义
      • 2. 类型不匹配
      • 3. 性能问题
      • 4. 复杂表达式调试

Aviator简介

核心优势

  • 🚀 高性能:通过编译成字节码实现,接近原生Java性能
  • 📦 轻量级:核心jar包仅几百KB,无第三方依赖
  • 🔢 大数运算:内置支持高精度计算(BigDecimal)
  • 🔌 可扩展:支持自定义函数和运算符重载
  • 📝 丰富语法:支持大多数Java运算符和函数调用

典型应用场景

  1. 动态规则计算(如风控规则、定价策略)
  2. 配置文件中的条件表达式
  3. 数据转换和格式化处理
  4. 数学公式计算引擎
  5. 模板引擎中的逻辑运算

核心特性详解

1. 类型系统

Aviator支持完整的Java类型系统,包括:

  • 基本类型:long/double/boolean等
  • 大数类型:BigInteger/BigDecimal
  • 集合类型:List/Map/Array
  • 自定义对象
// 类型声明示例\"{long} a + b\" // 强制返回long类型\"{double} 1/2\" // 返回0.5而非0
2. 运算符支持
运算符类型 支持示例 算术运算 + - * / % 比较运算 > >= < <= == != 逻辑运算 && || ! 位运算 & | ^ ~ <> 三元运算 a > b ? a : b
3. 内置函数
  • 数学函数:sqrt()/sin()/log()
  • 字符串函数:substring()/trim()
  • 集合函数:map()/filter()/reduce()
  • 日期函数:now()/date_add()

自定义函数参考表

函数名称 语法示例 功能描述 实现类 特殊字符变量 $(\'var.name\') 处理带特殊字符的变量名 DotVariableFunction 数组访问 array(arr, index) 获取数组指定下标元素 ArrayFunction 位操作 bitSeq(num, pos) 获取数字指定位的值(0/1) BitSeqFunction 类型转换 {type}expr 强制转换表达式结果类型 TypeUtil

自定义函数实现要点

  1. 继承AbstractFunction或现有函数基类
  2. 实现call()方法处理参数
  3. 通过getName()声明函数名称
  4. 注册到AviatorEvaluatorInstance

本文主要介绍aviator在处理简单运算、特殊字符运算、bit运算、数组运算方面的解决办法。

Spring Boot集成

1. Maven依赖

<dependencies>  <dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>5.4.1</version>  </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.28</version> </dependency></dependencies>

2. Expression类结构

/** * 表达式封装类,实现Serializable以便序列化 */public class ExpressionTest implements Serializable {  private static final long serialVersionUID = -1341923453630055435L; // 自定义函数名称常量 private static final String ARRAY_FUNCTION = \"array\"; private static final String BIT_SEQ_FUNCTION = \"bitSeq\"; // Aviator表达式实例(transient不序列化,volatile保证可见性) private transient volatile Expression expression; // 表达式中的变量列表 private List<String> variables; // 原始表达式字符串 private String expr; // 类型声明(如{long}) private String typeDeclaration; // 正则表达式模式 private final Pattern pattern = Pattern.compile(\"\\\\$\\\\(\'([^\']*)\'\"); //判断返回值类型 private final Pattern patternType = Pattern.compile(\"\\\\{([^}]*)\\\\}\\\\s*(.*)\"); public ExpressionTest(String expr) {  extractExpression(expr); this.expression = buildExpression(expr); variables = getVariables(); } }

3. 表达式构建方法

/** * 构建Aviator表达式 * @param expr 表达式字符串 * @return 编译后的表达式 */private Expression buildExpression(String expr) {  // 注册自定义函数 Expression compiledExp = null; try {  AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance(); registerFunctionIfAbsent(instance, ExternalField.variableMark, new DotVariableFunction()); registerFunctionIfAbsent(instance, ARRAY_FUNCTION, new ArrayFunction()); registerFunctionIfAbsent(instance, BIT_SEQ_FUNCTION, new BitSeqFunction()); compiledExp = AviatorEvaluator.compile(this.expr, true); } catch (Exception e) {  // 构建计算表达式错误 log.error(\"Error in constructing the calculation expression: {}\", expr, e); } return compiledExp; }/** * 函数不存在时注册 */private static void registerFunctionIfAbsent(AviatorEvaluatorInstance instance, String functionName, AviatorFunction function) {  if (MapUtils.isEmpty(instance.getFuncMap()) || !instance.getFuncMap().containsKey(functionName)) {  instance.addFunction(function); }}

4.类型转换类

public class TypeUtil {  public static BigDecimal toBigDecimal(Object value) {  if (value instanceof Byte) {  return new BigDecimal((Byte) value); } if (value instanceof Short) {  return new BigDecimal((Short) value); } if (value instanceof Integer) {  return new BigDecimal((Integer) value); } if (value instanceof Long) {  return new BigDecimal((Long) value); } if (value instanceof Float) {  return BigDecimal.valueOf((Float) value); } if (value instanceof Double) {  return BigDecimal.valueOf((Double) value); } if (value instanceof String) {  return new BigDecimal((String) value); } if (value instanceof BigDecimal) {  return (BigDecimal) value; } return null; } /** * 进行数据转化 * * @param value * @param targetType * @param  * @return */ public static <T> T convertToType(Object value, Class<T> targetType) {  BigDecimal bigDecimalValue; try {  bigDecimalValue = Optional.ofNullable(value)  .map(val -> new BigDecimal(value.toString())).get(); } catch (Exception e) {  return (T) value; } if (BigDecimal.class.equals(targetType)) {  return targetType.cast(bigDecimalValue); } if (Number.class.isAssignableFrom(targetType)) {  try {  if (targetType == Double.class || targetType == double.class) {   return targetType.cast(bigDecimalValue.doubleValue()); } else if (targetType == Float.class || targetType == float.class) {   return targetType.cast(bigDecimalValue.floatValue()); } else if (targetType == Long.class || targetType == long.class) {   return targetType.cast(bigDecimalValue.longValue()); } else if (targetType == Integer.class || targetType == int.class) {   return targetType.cast(bigDecimalValue.intValue()); } else if (targetType == Short.class || targetType == short.class) {   return targetType.cast(bigDecimalValue.shortValue()); } else if (targetType == Byte.class || targetType == byte.class) {   return targetType.cast(bigDecimalValue.byteValue());</