Spring EL(表达式语言)零基础教程

Spring EL(表达式语言)零基础全面教程

一、什么是Spring EL?

Spring Expression Language(简称 SpEL)是 Spring 框架提供的一种强大的表达式语言,用于在运行时查询和操作对象。它支持属性访问、方法调用、运算符、条件判断等功能,广泛应用于 Spring 配置、注解(如 @Value)、安全规则(Spring Security)等场景。

二、基础语法

SpEL 表达式以 #{ } 包裹,基本结构为:

#{表达式}

1. 字面量

  • 字符串:#{'Hello World'}
  • 数字:#{3.14}
  • 布尔值:#{true}

2. 变量引用

使用 #变量名 引用上下文中的变量:

#{user.name}  // 引用 user 对象的 name 属性

$ vs #${} 用于属性占位符(如 application.properties),#{} 用于 SpEL 表达式。

3. 方法调用

#{'abc'.toUpperCase()}  // 结果为 "ABC"

4. 操作符

  • 算术:+, -, *, /, %
  • 比较:==, !=, <, >, <=, >=
  • 逻辑:and, or, not
  • 三元运算符:条件 ? 结果1 : 结果2

三、集合与数组操作

1. 访问列表/数组

#{users[0].name}  // 访问第一个用户的 name 属性

2. 访问字典(Map)

#{userMap['admin'].password}  // 获取 key 为 'admin' 的用户的密码

3. 安全导航操作符(?.)

避免空指针异常:

#{user?.address?.city}  // 若 user 或 address 为 null,返回 null

4. 集合过滤与投影

  • 选择(过滤):?[...]

    #{users.?[age > 18]}  // 筛选年龄大于 18 的用户
    

  • 投影(提取属性):! [...]

    #{users.![name]}  // 提取所有用户的 name 属性,生成列表
    

四、类型操作符(T())

通过 T() 引用类,调用静态方法或常量:

#{T(java.lang.Math).random()}  // 调用 Math.random()
#{T(java.util.Locale).CHINA}   // 引用 Locale.CHINA 常量

五、高级特性

1. Bean 引用

在表达式中引用 Spring 容器中的 Bean:

#{@myService.getData()}  // 调用名为 myService 的 Bean 的 getData 方法

2. 条件表达式(if-else)

#{user.vip ? '尊享会员' : '普通用户'}

3. 正则表达式匹配

#{user.email matches '[a-zA-Z0-9._%+-]+@gmail\\.com'}

4. 模板表达式

结合文本与表达式:

#{'用户名为:' + user.name + ',年龄:' + user.age}

六、实际应用场景

1. 在 @Value 中注入动态值

@Value("#{systemProperties['user.dir']}")
private String workDir;

2. Spring Security 权限控制

@PreAuthorize("hasRole('ADMIN') or #user.id == authentication.principal.id")
public void updateUser(User user) { ... }

3. XML 配置中的 SpEL

<bean id="dataSource" class="com.example.DataSource">
  <property name="timeout" value="#{T(java.lang.Math).random() * 100}"/>
</bean>

4. 动态数据过滤

结合 Spring Data JPA:

@Query("SELECT u FROM User u WHERE u.name = ?#{#name}")
List<User> findByName(String name);

七、常见问题

SpEL 与 OGNL/JSTL 的区别?

SpEL 专为 Spring 设计,支持类型安全和方法调用,与 Spring 生态深度集成。

如何调试 SpEL 表达式?

使用 ExpressionParser 解析表达式,捕获 EvaluationException

ExpressionParser parser = new SpelExpressionParser();
try {
    parser.parseExpression("#{user.age}").getValue(context);
} catch (EvaluationException e) {
    e.printStackTrace();
}

性能如何?

SpEL 在启动时解析表达式并缓存,运行时性能接近 Java 代码。

八、总结

  • 适用场景:动态配置、条件注入、安全规则、数据过滤。
  • 核心优势:灵活性高,与 Spring 无缝集成。
  • 学习建议:多实践,结合 Spring 的 @Value@PreAuthorize 等注解使用。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值