「抛弃 if-else!」这 5 款 Java 表达式引擎,让你的代码更优雅!

前言

在设计一些表单或者流程引擎时,我们可能需要用各种表达式或者规则来实现业务流转。今天就来盘点一些常用的 Java 表达式引擎,帮助大家更高效地处理动态逻辑。

以下介绍的表达式引擎都是开发者耳熟能详的工具,让我们一起回顾它们的特点和使用方式吧!


1. Spring Expression Language (SpEL)

官方资源

核心特点

SpEL 是 Spring 框架内置的表达式语言,广泛应用于 Bean 配置、Spring Security、Spring Data 查询等模块中。它的特点包括:

  1. 动态查询和操作对象:支持属性访问、方法调用、算术运算、逻辑判断等。
  2. 上下文感知:可直接访问 Spring 容器中的 Bean 和上下文环境中的变量。
  3. 类型转换:内置类型转换服务,支持自动或显式的类型转换。
  4. 安全性:支持限制表达式的执行能力,避免注入攻击。

示例

// 访问 Bean 属性
#{myBean.propertyName}  

// 方法调用
#{myBean.myMethod(args)}  

// 三元运算
#{condition ? trueValue : falseValue}  

// 列表访问
#{myList[0]}  

工具类

public class SpringExpressionUtil {
    private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();

    public static <T> T evaluateExpression(Map<String, Object> rootObject, String expressionString, Class<T> returnType) {
        StandardEvaluationContext context = new StandardEvaluationContext(rootObject);
        rootObject.forEach(context::setVariable);
        return EXPRESSION_PARSER.parseExpression(expressionString).getValue(context, returnType);
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "lybgeek");
        System.out.println(evaluateExpression(map, "#root.get('name')", String.class));
    }
}

2. OGNL (Object-Graph Navigation Language)

官方资源

核心特点

OGNL 是一种专注于对象图操作的表达式语言,常用于 Apache Struts2 等框架中。

  1. 链式导航:支持通过简单语法深入对象属性,如 person.name
  2. 集合操作:直接在表达式中处理集合,如过滤或投影。
  3. 方法调用与赋值:支持调用方法以及为对象属性赋值。
  4. 安全性:需要防止用户输入的表达式被直接解析,避免注入风险。

工具类

public class OgnlExpressionUtil {
    public static <T> T evaluateExpression(Map<String, Object> rootObject, String expressionString, Class<T> returnType) {
        Object value = OgnlCache.getValue(expressionString, rootObject);
        return value != null && value.getClass().isAssignableFrom(returnType) ? (T) value : null;
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "lybgeek");
        System.out.println(evaluateExpression(map, "#root.name", String.class));
    }
}

3. Aviator

官方资源

核心特点

Aviator 是一款高性能的轻量级表达式引擎,专注于动态计算场景:

  1. 高性能:通过 JIT 编译技术优化表达式执行效率。
  2. 丰富的运算支持:支持数学运算、逻辑判断、字符串操作等。
  3. 安全沙箱:可限制表达式的执行权限,提高安全性。

工具类

public final class AviatorExpressionUtil {
    public static <T> T evaluateExpression(Map<String, Object> env, String expression, Class<T> returnType) {
        Object value = AviatorEvaluator.execute(expression, env);
        return value != null && value.getClass().isAssignableFrom(returnType) ? (T) value : null;
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "lybgeek");
        System.out.println(evaluateExpression(map, "name", String.class));
    }
}

4. MVEL2

官方资源

核心特点

MVEL2 是一款功能全面的表达式引擎:

  1. 支持控制流:内置 iffor 等语法。
  2. 模板引擎:可以生成动态文本输出。
  3. 扩展性:支持自定义函数和操作符,灵活满足业务需求。

5. Hutool ExpressionUtil

官方资源

Hutool 从 5.5.0 版本开始提供统一的表达式引擎门面,支持以下多种引擎:

  • Aviator
  • Apache Jexl3
  • MVEL
  • Spring EL

工具类

public class HutoolExpressionUtil {
    public static <T> T evaluateExpression(Map<String, Object> variables, String expression, Class<T> returnType) {
        Object value = ExpressionUtil.eval(expression, variables);
        return value != null && value.getClass().isAssignableFrom(returnType) ? (T) value : null;
    }

    public static void main(String[] args) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("name", "lybgeek");
        System.out.println(evaluateExpression(variables, "name", String.class));
    }
}

总结

本文盘点了 5 款主流的 Java 表达式引擎,它们各具特色且功能强大。如果对引擎选择有疑惑,Hutool 的表达式引擎门面是一个值得尝试的统一解决方案,提供了便捷的封装和灵活性。