public static void main(String[] args) {
        String exp = "本金*(1+年数*年利率)" ;
        // Dict为hutool
        Object a = Dict.create().set("本金", 100).set("年数",2).set("年利率", 0.1);
        Object obj = MVEL.eval(exp,a);
        System.out.println(obj);
    }

表达式性能对比

public static void main(String[] args) throws Exception {
        long s = System.currentTimeMillis();
//        ScriptEngine js = new ScriptEngineManager().getEngineByName("js");
//        GroovyScriptEvaluator groovyScriptEvaluator = new GroovyScriptEvaluator();
//        GroovyShell groovyShell = new GroovyShell();
//        ExpressRunner runner = new ExpressRunner();
//        ExpressionParser parser = new SpelExpressionParser();
//        Context context = Context.newBuilder().allowAllAccess(true).build();
//        JexlScriptEngine engine = new JexlScriptEngine();
        for (int i = 0; i < 10000; i++) {
//            Object eval = Integer.valueOf(1 * i);
//            Object eval = js.eval("1 * " + i);
//            Object eval = groovyScriptEvaluator.evaluate(new StaticScriptSource("1 * " + i));
//            Object eval = groovyShell.evaluate("1 * " + i);
//            Object eval = runner.execute("1 * " + i, null, null, true, false);
//            Object eval = MVEL.eval("1 * " + i);
//            Object eval = parser.parseExpression("1 * " + i).getValue();
//            Value eval = context.eval("js", "1 * " + i);
//            Object eval = engine.eval("1 * " + i);
            Object eval = AviatorEvaluator.execute("1 * " + i);
            System.out.println("1 * " + i + " = " + eval);
        }
        long e = System.currentTimeMillis();
        System.out.println("take " + (e-s));

        // 单位ms
        // java 119
        // MVEL 345  
        // SpEL 418
        // aviator 711   compile模式500  cache模式400
        // QLExpress 1507 
        // jexl3 1706
        // graalvm js 2245
        // ScriptEngine js 14988
        // groovyEvaluator 58781
        // groovyShell 40536
    }

结论

  • 表达式引擎比脚本引擎效率高
  • 脚本引擎功能更强,支持直接调用java方法api

MVEL

支持条件、循环、函数、调用自定义java方法
入门http://t.zoukankan.com/firstdream-p-6651078.html
官方https://github.com/mvel/mvel
自定义java方法https://blog.csdn.net/jian876601394/article/details/110410374

SpEL

spring内置,可调用一些java api,不支持循环
https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/expressions.html

aviator

** 不得不提一句,谷歌大法好 **,开启编译和缓存模式后,性能提升一倍

// 编译并开启缓存
Expression compile = AviatorEvaluator.compile("1 * param", true); 
// 清除缓存
AviatorEvaluator.invalidateCache("1 * param"); 

支持正则、try catch、导入java包,google背书
https://www.yuque.com/boyan-avfmj/aviatorscript/cpow90

以下是脚本引擎

QLExpress

支持条件、循环、函数,alibaba背书
https://github.com/alibaba/QLExpress

graalvm

支持多语言:ruby,js,python,groovy,kotlin等,eclipse、oracle背书

maven依赖

<!-- aviator表达式引擎支持 -->
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.2.7</version>
        </dependency>
        <!-- jexl3表达式引擎支持 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-jexl3</artifactId>
            <version>3.2.1</version>
        </dependency>
        <!-- javascript-graalvm支持 -->
        <dependency>
            <groupId>org.eclipse.dirigible</groupId>
            <artifactId>dirigible-engine-javascript-graalvm</artifactId>
            <version>5.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.mvel</groupId>
            <artifactId>mvel2</artifactId>
            <version>2.4.8.Final</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>QLExpress</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>3.0.8</version>
        </dependency>