偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

誰更快?Spring Boot 七大表達(dá)式引擎,哪個(gè)更適合你

開發(fā) 前端
Spring Boot 作為 Java 生態(tài)中最流行的開發(fā)框架,支持多種表達(dá)式引擎,如 SpEL(Spring Expression Language)、MVEL、Aviator 等,每種引擎在性能、語法復(fù)雜度、適用場(chǎng)景上各有優(yōu)劣。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

在企業(yè)級(jí)應(yīng)用開發(fā)中,動(dòng)態(tài)表達(dá)式解析已成為實(shí)現(xiàn)靈活業(yè)務(wù)邏輯的關(guān)鍵技術(shù)。無論是規(guī)則引擎、動(dòng)態(tài)配置、公式計(jì)算,還是權(quán)限控制,表達(dá)式引擎都能大幅提升系統(tǒng)的可擴(kuò)展性和可維護(hù)性。

Spring Boot 作為 Java 生態(tài)中最流行的開發(fā)框架,支持多種表達(dá)式引擎,如 SpEL(Spring Expression Language)、MVEL、Aviator 等,每種引擎在性能、語法復(fù)雜度、適用場(chǎng)景上各有優(yōu)劣。例如:

  • SpEL 深度集成 Spring,適合安全要求高的場(chǎng)景
  • MVEL 支持完整腳本,適合復(fù)雜規(guī)則引擎
  • Aviator 專注高性能計(jì)算,適合金融、大數(shù)據(jù)分析
  • JEP 擅長(zhǎng)數(shù)學(xué)運(yùn)算,適用于科學(xué)計(jì)算
  • OGNL 在 MyBatis 等框架中仍有應(yīng)用,但需注意安全風(fēng)險(xiǎn)
  • JEXL 語法簡(jiǎn)單,適合輕量級(jí)動(dòng)態(tài)配置
  • QLExpress 適合各種復(fù)雜規(guī)則解析運(yùn)算

本文將從性能、安全性、語法易用性等維度,結(jié)合完整代碼示例,深入對(duì)比六大引擎,幫助開發(fā)者選型并優(yōu)化業(yè)務(wù)邏輯! ??

2.實(shí)戰(zhàn)案例

2.1 SpEL表達(dá)式

SpEL(Spring Expression Language)是Spring框架的強(qiáng)大表達(dá)式語言,支持在運(yùn)行時(shí)查詢和操作對(duì)象圖。它語法簡(jiǎn)潔靈活,可進(jìn)行屬性訪問、方法調(diào)用、算術(shù)運(yùn)算、集合操作等,廣泛應(yīng)用于配置管理、條件注入等場(chǎng)景,提升開發(fā)效率。如下代碼示例:

@RestController
public class SpELController {
  @GetMapping("/spel")
  public String evaluate() {
    ExpressionParser parser = new SpelExpressionParser();
    // 基本運(yùn)算
    Expression exp1 = parser.parseExpression("2 * 3 + 5");
    int result1 = exp1.getValue(Integer.class);
    // 字符串操作
    Expression exp2 = parser.parseExpression("'SPEL'.toLowerCase()");
    String result2 = exp2.getValue(String.class);
    // 集合操作
    Expression exp3 = parser.parseExpression("{1,2,3,4}.?[#this > 2]");
    Object result3 = exp3.getValue();
    return String.format("""
        SpEL 結(jié)果:<br/>
        基本運(yùn)算: 2*3+5 = %d<br/>
        字符串操作: 'SPEL'.toLowerCase() = %s<br/>
        集合過濾: {1,2,3,4}.?[#this > 2] = %s<br/>
        """, result1, result2, result3);
  }
}

運(yùn)行結(jié)果:

圖片圖片

優(yōu)點(diǎn):

  • 語法靈活,能靈活查詢操作對(duì)象圖,滿足多樣需求;
  • 可解耦合,使邏輯與實(shí)現(xiàn)分離,提升代碼可維護(hù)性;
  • 具備動(dòng)態(tài)性,運(yùn)行時(shí)動(dòng)態(tài)評(píng)估表達(dá)式,適應(yīng)不同條件;
  • 還提供統(tǒng)一語法,降低學(xué)習(xí)成本,功能也豐富多樣。

缺點(diǎn):

  • 學(xué)習(xí)有一定曲線,新手需要點(diǎn)時(shí)間掌握;
  • 運(yùn)行時(shí)動(dòng)態(tài)計(jì)算可能帶來性能開銷,影響高性能應(yīng)用;
  • 且若處理不當(dāng),存在安全風(fēng)險(xiǎn),如惡意表達(dá)式可能引發(fā)任意命令執(zhí)行等安全問題,使用時(shí)需謹(jǐn)慎。

2.2 MVEL

MVEL(MVFLEX Expression Language)是一種基于Java的輕量級(jí)表達(dá)式語言,語法簡(jiǎn)潔易讀,支持算術(shù)、邏輯、字符串操作等。它可與Java無縫集成,動(dòng)態(tài)解析執(zhí)行表達(dá)式,適用于規(guī)則引擎、模板引擎等場(chǎng)景,能提升開發(fā)效率與代碼靈活性。

引入依賴:

<dependency>
  <groupId>org.mvel</groupId>
  <artifactId>mvel2</artifactId>
  <version>2.5.2.Final</version>
</dependency>

如下示例:

@RestController
public class MVELController {
  @GetMapping("/mvel")
  public String evaluate() {
    // 編譯表達(dá)式提高性能
    Serializable exp1 = MVEL.compileExpression("a * b + c");
    Map<String, Object> vars = new HashMap<>();
    vars.put("a", 5);
    vars.put("b", 3);
    vars.put("c", 2);
    int result1 = MVEL.executeExpression(exp1, vars, Integer.class);
    // 復(fù)雜邏輯
    String exp2 = "if (x > y) { x * 2 } else { y * 3 }";
    vars.put("x", 8);
    vars.put("y", 10);
    int result2 = MVEL.eval(exp2, vars, Integer.class);
    // 集合操作
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    Map<String, Object> vars1 = new HashMap<>();
    vars1.put("list", list);
    // 使用 MVEL 表達(dá)式進(jìn)行過濾并求和
    String exp = "sum = 0; for (n : list) { if (n % 2 == 0) sum += n }; sum";
    Integer result3 = (Integer) MVEL.eval(exp, vars1);
    return String.format("""
        MVEL 結(jié)果:<br/>
        基本運(yùn)算: a*b+c = %d<br/>
        條件邏輯: if (x>y) x*2 else y*3 = %d<br/>
        集合操作: 偶數(shù)和 = %d
        """, result1, result2, result3);
  }
}

運(yùn)行結(jié)果:

圖片圖片

優(yōu)點(diǎn):

語法簡(jiǎn)潔、集成方便、執(zhí)行效率較高,適合用于規(guī)則引擎、動(dòng)態(tài)配置等場(chǎng)景。它支持類型推斷、集合操作和部分函數(shù)式編程特性,與 Spring 等框架有良好集成。

缺點(diǎn):

它并不完全支持 Java 語法,特別是對(duì) Stream API 不兼容?,容易造成誤解和使用障礙。對(duì)復(fù)雜邏輯支持較弱,調(diào)試和錯(cuò)誤提示不夠友好。

2.3 Aviator

Aviator是一個(gè)高性能、輕量級(jí)的Java表達(dá)式求值引擎。它支持?jǐn)?shù)學(xué)運(yùn)算、邏輯運(yùn)算等,能將表達(dá)式編譯成Java字節(jié)碼執(zhí)行,性能優(yōu)越。還提供簡(jiǎn)潔API與豐富語法,支持自定義函數(shù),可靈活集成到Java項(xiàng)目中,滿足動(dòng)態(tài)計(jì)算等需求。

引入依賴:

<dependency>
  <groupId>com.googlecode.aviator</groupId>
  <artifactId>aviator</artifactId>
  <version>5.4.3</version>
</dependency>

如下示例:

@RestController
public class AviatorController {
  @GetMapping("/aviator")
  public String evaluate() {
    // 基本運(yùn)算
    Double result1 = (Double) AviatorEvaluator.execute("2 ** 10 + math.sqrt(100)");
    // 使用變量
    Map<String, Object> env = new HashMap<>();
    env.put("name", "Aviator");
    env.put("score", 95.5);
    String result2 = (String) AviatorEvaluator.execute("name + ' score: ' + score", env);
    // 大數(shù)運(yùn)算
    String result3 = AviatorEvaluator.execute("999999999999999999 * 888888888888888888").toString();
    // 自定義函數(shù)
    AviatorEvaluator.addFunction(new CustomFunction());
    Double result4 = (Double) AviatorEvaluator.execute("square_root(144)");
    return String.format("""
        Aviator 結(jié)果:<br/>
        基本運(yùn)算: 2^10 + sqrt(100) = %s<br/>
        變量使用: %s<br/>
        大數(shù)運(yùn)算: 999... * 888... = %s<br/>
        自定義函數(shù): square_root(144) = %s
        """, result1, result2, result3, result4);
  }
  static class CustomFunction extends com.googlecode.aviator.runtime.function.AbstractFunction {
    private static final long serialVersionUID = 1L;
    @Override
    public String getName() {
      return "square_root";
    }
    @Override
    public com.googlecode.aviator.runtime.type.AviatorObject call(Map<String, Object> env,
        com.googlecode.aviator.runtime.type.AviatorObject arg1) {
      Long num = (Long) arg1.getValue(env);
      return new com.googlecode.aviator.runtime.type.AviatorDouble(Math.sqrt(num));
    }
  }
}

運(yùn)行結(jié)果:

圖片圖片

優(yōu)點(diǎn):

  • 高性能,它直接將表達(dá)式編譯成Java字節(jié)碼交給JVM執(zhí)行
  • 易用性佳,提供簡(jiǎn)潔API和豐富語法
  • 可擴(kuò)展性強(qiáng),支持自定義函數(shù)和操作符
  • 還具備運(yùn)行時(shí)安全性。

缺點(diǎn):

  • 語法受限,不是完整語言,沒有if else、do while等語句和賦值語句
  • 對(duì)日期類型支持不足,需將日期寫成特定格式字符串比較
  • 且不支持八進(jìn)制數(shù)字字面量,僅支持十進(jìn)制和十六進(jìn)制數(shù)字字面量

2.4 JEP

JEP是Java Expression Parser(Java表達(dá)式分析器)的簡(jiǎn)稱,是用于轉(zhuǎn)換和計(jì)算數(shù)學(xué)表達(dá)式的Java庫,支持自定義變量、常量和函數(shù),能快速求值。

引入依賴:

<dependency>
  <groupId>org.scijava</groupId>
  <artifactId>jep</artifactId>
  <version>2.4.2</version>
</dependency>

代碼示例:

@RestController
public class JEPController {
  @GetMapping("/jep")
  public String evaluate() {
    JEP jep = new JEP() ;
    jep.addStandardFunctions(); 
    jep.addStandardConstants();
    // 基本數(shù)學(xué)運(yùn)算
    jep.parseExpression("sin(pi/2) + log(100)") ;
    double result1 = jep.getValue();
    // 多變量計(jì)算
    jep.addVariable("x", 3);
    jep.addVariable("y", 4);
    jep.parseExpression("x^2 + y^2");
    double result2 = jep.getValue();
    return String.format("""
        JEP 結(jié)果:<br/>
        三角函數(shù): sin(π/2) + log(100) = %.1f<br/>
        多變量: x2 + y2 = %.1f
        """, result1, result2);
  }
}

運(yùn)行結(jié)果:

圖片圖片

JEP非常使用數(shù)學(xué)運(yùn)算,詳細(xì)可以查看上面 addStandardFunctions 方法中添加的默認(rèn)函數(shù)功能。

2.5 Ognl

OGNL 是一種功能強(qiáng)大的表達(dá)式語言,用于訪問和操作 Java 對(duì)象圖。它支持屬性導(dǎo)航、方法調(diào)用、集合投影/過濾、Lambda 表達(dá)式等,廣泛應(yīng)用于 Struts2 等框架。通過簡(jiǎn)潔語法(如 obj.property 或 collection.{property}),可高效操作復(fù)雜對(duì)象結(jié)構(gòu),簡(jiǎn)化數(shù)據(jù)綁定與邏輯處理。

引入依賴:

<dependency>
  <groupId>ognl</groupId>
  <artifactId>ognl</artifactId>
  <version>3.4.7</version>
</dependency>

示例代碼:

@RestController
public class OGNLController {
  public static class User {
    public String name;
    public Address address;
    public User(String name, Address address) {
      this.name = name;
      this.address = address;
    }
  }
  public static class Address {
    public String city;
    public String street;
    public Address(String city, String street) {
      this.city = city;
      this.street = street;
    }
  }
  @GetMapping("/ognl")
  public String evaluate() throws OgnlException {
    User user = new User("Tom", new Address("Beijing", "Chang'an Street"));
    // 對(duì)象圖導(dǎo)航
    String city = (String) Ognl.getValue("address.city", user); 
    // 方法調(diào)用
    String upperName = (String) Ognl.getValue("name.toUpperCase()", user);
    // 集合投影
    List<User> users = List.of(
        new User("Alice", new Address("Shanghai", "Nanjing Road")),
        new User("Bob", new Address("Guangzhou", "Zhongshan Road"))
        );
    OgnlContext context = (OgnlContext) Ognl.createDefaultContext(users);
    context.put("users", users);
    // 使用OGNL表達(dá)式進(jìn)行投影操作,獲取所有人的年齡
    String expression = "#users.{name}";
    Object names = Ognl.getValue(expression, context, context.getRoot());
    return String.format("""
        OGNL 結(jié)果:<br/>
        對(duì)象導(dǎo)航: address.city = %s<br/>
        方法調(diào)用: name.toUpperCase() = %s<br/>
        集合投影: users.{name} = %s
        """, city, upperName, names);
  }
}

運(yùn)行結(jié)果:

圖片圖片

優(yōu)點(diǎn):

  • 語法簡(jiǎn)潔靈活,能以少量代碼實(shí)現(xiàn)復(fù)雜操作,降低開發(fā)成本
  • 支持對(duì)象方法調(diào)用、靜態(tài)方法調(diào)用和值訪問,還能操作集合對(duì)象,功能強(qiáng)大
  • 可訪問OGNL上下文和ActionContext,方便數(shù)據(jù)交互
  • 能對(duì)集合進(jìn)行過濾和投影等操作,提升數(shù)據(jù)處理能力

缺點(diǎn):

  • 解析和執(zhí)行需消耗一定時(shí)間和資源,可能影響應(yīng)用性能
  • 存在安全風(fēng)險(xiǎn),如注入攻擊、數(shù)據(jù)竊取等
  • 在復(fù)雜表達(dá)式中,代碼可維護(hù)性會(huì)降低,且其表達(dá)式計(jì)算圍繞上下文進(jìn)行,使用不當(dāng)易出錯(cuò)

2.6 JEXL

JEXL 實(shí)現(xiàn)了一種基于 JSTL(JavaServer Pages Standard Tag Library)表達(dá)式語言擴(kuò)展的表達(dá)式語言,支持 shell 腳本或 ECMAScript 中常見的大部分結(jié)構(gòu)。其目標(biāo)是向在企業(yè)平臺(tái)上工作的技術(shù)人員或顧問暴露可用的腳本功能。在許多使用場(chǎng)景中,JEXL 允許應(yīng)用程序的最終用戶編寫自己的腳本或表達(dá)式,并確保這些腳本或表達(dá)式在受控的功能約束范圍內(nèi)執(zhí)行。

引入依賴:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-jexl3</artifactId>
  <version>3.5.0</version>
</dependency>

示例代碼:

@RestController
public class JEXLController {
  @GetMapping("/jexl")
  public String evaluate() {
    JexlEngine jexl = new JexlBuilder().create();
    // 簡(jiǎn)單表達(dá)式
    JexlExpression exp1 = jexl.createExpression("'Hello ' + name");
    JexlContext context1 = new MapContext();
    context1.set("name", "JEXL");
    String result1 = exp1.evaluate(context1).toString(); // "Hello JEXL"
    // 條件判斷
    JexlExpression exp2 = jexl.createExpression("age >= 18 ? 'Adult' : 'Minor'");
    JexlContext context2 = new MapContext();
    context2.set("age", 20);
    String result2 = exp2.evaluate(context2).toString(); // "Adult"
    // 循環(huán)操作
    JexlScript script = jexl.createScript("""
            total = 0;
            for (n : numbers) {
                total += n
            }
            return total
        """);
    JexlContext context3 = new MapContext();
    context3.set("numbers", new int[] { 1, 2, 3, 4, 5 });
    Object result3 = script.execute(context3); // 15
    return String.format("""
        JEXL 結(jié)果:<br/>
        字符串拼接: %s<br/>
        條件判斷: %s<br/>
        循環(huán)求和: %d
        """, result1, result2, result3);
  }
}

運(yùn)行結(jié)果:

圖片圖片

優(yōu)點(diǎn):

  • 語法簡(jiǎn)潔直觀,易于學(xué)習(xí)和使用,能降低開發(fā)門檻
  • 與Java集成良好,可輕松與Java對(duì)象交互,利用反射機(jī)制訪問類和方法
  • 靈活性高,支持自定義函數(shù)、變量和操作符,滿足多樣化需求
  • 提供安全沙箱機(jī)制,限制腳本對(duì)系統(tǒng)資源的訪問,增強(qiáng)安全性
  • 具有跨平臺(tái)特性,可在不同操作系統(tǒng)和硬件架構(gòu)上運(yùn)行

缺點(diǎn):

  • 缺少規(guī)則管理功能,如規(guī)則編輯、版本控制等需自行實(shí)現(xiàn)或借助其他工具
  • 執(zhí)行效率相對(duì)較低,雖可通過動(dòng)態(tài)編譯技術(shù)提升,但會(huì)增加額外轉(zhuǎn)換步驟
責(zé)任編輯:武曉燕 來源: Springboot全家桶實(shí)戰(zhàn)案例
相關(guān)推薦

2024-04-03 08:28:31

GolangPHP語言

2023-10-10 08:36:57

數(shù)據(jù)庫MyISMInnoDB

2021-09-17 13:17:56

Spring 模塊開發(fā)

2021-12-03 10:15:10

FlowTypescript開發(fā)

2017-06-27 15:08:05

大數(shù)據(jù)Apache SparKafka Strea

2009-02-25 19:47:54

IT認(rèn)證思科認(rèn)證微軟認(rèn)證

2009-09-16 17:15:57

正則表達(dá)式引擎

2012-02-14 09:40:00

HTML 5AndroidiOS

2021-07-30 11:16:38

云存儲(chǔ)本地存儲(chǔ)

2021-12-07 11:18:40

前端代碼規(guī)范工具開發(fā)

2023-08-29 11:37:10

云計(jì)算數(shù)據(jù)中心

2024-10-10 14:43:54

LambdaSpring編程

2009-03-17 08:33:22

Windows7節(jié)省開支

2010-07-13 16:15:49

XenServer5.6

2013-07-22 15:36:48

谷歌秘密項(xiàng)目

2015-08-20 09:57:42

WiFiBOT模式PPP模式

2010-07-26 16:44:45

2022-01-26 10:26:57

ChromeBrave網(wǎng)頁瀏覽器

2015-09-16 11:29:46

超融合架構(gòu)軟件定義存儲(chǔ)

2022-01-25 19:36:46

ChromeBrave瀏覽器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)