首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 學習總結(四):Spring Expression Language (SpEL) 表達式語言完全指南

     編輯:Java 綜合教學

SpEL 簡介

Spring Expression Language (SpEL) 是一個強大的運行時表達式語言,支持查詢和操作對象圖。語法類似 Unified EL,但提供方法調用、構造函數調用、正則匹配、集合投影/選擇、模板表達式等高級特性。SpEL 獨立於 Spring 容器,可單獨使用。

核心 API 入門

// 1. 解析器
ExpressionParser parser = new SpelExpressionParser();

// 2. 解析表達式字符串
Expression exp = parser.parseExpression("'Hello ' + 'World!'");

// 3. 獲取值(可指定類型)
String result = exp.getValue(String.class); // "Hello World!"

// 4. 設置上下文(訪問 Bean/變量)
EvaluationContext ctx = new StandardEvaluationContext();
ctx.setVariable("user", new User(1, "Alice"));
Integer id = parser.parseExpression("#user.id + 100").getValue(ctx, Integer.class); // 101

SpEL 表達式分類速查

類別語法示例說明
字面量'Hello', 3.14, 0xFF, true, null字符串用單引號,轉義用反斜杠
屬性訪問user.name, user['name'], list[0], map['key']點號/中括號,支持嵌套
方法調用user.getName(), 'abc'.substring(1,2), T(Math).random()T() 訪問類靜態方法/常量
構造調用new String('hello'), new ArrayList()直接實例化
運算符+ - * / % ^, == eq != ne < lt > gt, and or not, matches, between不支持 && ||,用 and or
三元/Elviscondition ? a : b, name ?: 'default'Elvis 操作符簡化非空判斷
正則'5.00' matches '^-?\\d+(\\.\\d{2})?$'返回 boolean
集合字面量{1,2,3} (List), {{'a','b'},{'c','d'}} (List<List>)不支持多維數組字面量、Map 字面量
集合投影users.![name] → List<String> 姓名集合對每個元素應用表達式收集結果
集合選擇users.?[age > 18] → 篩選成年用戶返回子集合
首尾選擇users.^[age > 18] (首個), users.$[age > 18] (最後)返回單個元素
變量賦值#var = 'value', #varName 引用在 EvaluationContext 中操作
模板表達式parser.parseExpression("Hello #{name}", new TemplateParserContext())#{...} 為表達式塊

XML 配置中使用 SpEL

<bean id="user" class="com.example.User" p:name="Alice" p:age="25"/>

<bean id="order" class="com.example.Order">
    <!-- 引用其他 Bean 屬性 -->
    <property name="customerName" value="#{user.name}"/>
    <!-- 調用方法/靜態方法 -->
    <property name="orderCode" value='#{T(java.util.UUID).randomUUID().toString()}'/>
    <property name="amount" value="#{T(java.lang.Math).random() * 100}"/>
    <!-- 系統屬性 -->
    <property name="env" value="#{systemProperties['user.region']}"/>
    <!-- Bean 間引用 -->
    <property name="relatedOrder" value="#{anotherOrder}"/>
</bean>

注解配置中使用 SpEL (@Value)

@Component
public class AppConfig {
    @Value("#{systemProperties['app.version']}")
    private String version;
    
    @Value("#{T(java.lang.Math).random() * 100}")
    private double randomScore;
    
    @Value("#{userService.defaultUser.name}") // 引用其他 Bean
    private String defaultUserName;
    
    @Value("#{'${app.prefix}' + '_' + T(java.util.UUID).randomUUID()}")
    private String generatedId; // 結合 ${...} 佔位符
}

高級特性實戰

集合投影與選擇

List<User> users = Arrays.asList(
    new User(1, "Alice", 20),
    new User(2, "Bob", 17),
    new User(3, "Carol", 25)
);
EvaluationContext ctx = new StandardEvaluationContext();
ctx.setVariable("users", users);

// 投影:提取所有名字
List<String> names = parser.parseExpression("#users.![name]").getValue(ctx, List.class);
// ["Alice", "Bob", "Carol"]

// 選擇:篩選成年用戶
List<User> adults = parser.parseExpression("#users.?[age >= 18]").getValue(ctx, List.class);
// [Alice, Carol]

// 首個匹配
User firstAdult = parser.parseExpression("#users.^[age >= 18]").getValue(ctx, User.class); // Alice

自定義函數註冊


模板表達式


SpEL vs 其他表達式語言

特性SpELOGNLJUEL
方法調用✓✓✗ (僅屬性)
構造調用✓✓✗
集合投影/選擇✓✓✗
模板表達式✓✗✗
類型訪問 T()✓✓ (@)✗
Spring 生態集成原生需適配標準

最佳實踐建議

  1. 優先在 @Value、XML 中使用 SpEL 注入配置,減少硬編碼
  2. 2. 複雜業務邏輯不要寫在 SpEL 中,放入 Service 方法再調用 3. 表達式字符串外部化至配置文件,支持熱加載 4. 使用 StandardEvaluationContext 緩存解析後的 Expression 對象,避免重複解析 5. 注意 SpEL 表達式注入風險:不可信輸入嚴禁直接作為表達式解析

SpEL 為 Spring 生態提供了統一、強大的表達式能力,掌握其核心語法與集成方式,能顯著提升配置靈活性與開發效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved