Spring Boot EL表达式学习笔记

一、EL表达式简介

Spring EL(Expression Language)是Spring框架中的表达式语言,支持在XML配置注解中动态调用资源。与JSP的EL表达式相比,Spring EL使用#{}语法,而JSP使用${}语法。主要功能包括:

  • 动态读取配置文件值
  • 调用Bean对象属性或方法
  • 支持条件化配置(如@ConditionalOnExpression

关键区别

  • @Value("${}"):从.properties.yml配置文件读取值
  • @Value("#{}"):从Spring容器中的Bean解析表达式

二、基础语法与应用场景

1. 注解中的EL表达式

1
2
3
4
5
6
7
8
9
10
11
// 注入配置文件中的端口号
@Value("${server.port}")
private String port;

// 调用Bean的userName属性
@Value("#{user.userName}")
private String userName;

// 条件化Bean加载(当表达式结果为true时生效)
@ConditionalOnExpression("#{environment.getProperty('mode') == 'dev'}")
public class DevConfig {}

代码说明

  • 配置文件注入需用${},Bean属性调用用#{}
  • @ConditionalOnExpression支持基于EL表达式的条件判断。

2. 安全控制中的EL表达式

在Spring Security中,EL表达式用于权限校验:

1
2
@PreAuthorize("hasRole('ADMIN') && #id == authentication.principal.id ")
public void deleteUser(String id) { ... }

常用表达式

  • hasRole('ADMIN'):检查角色
  • authentication.name:获取当前认证用户

三、高级用法

1. 动态生成缓存键(结合AOP)

1
2
@Cacheable(key = "#userId + '_' + #category")
public List<Item> getItems(String userId, String category) { ... }

解析上下文
通过EvaluationContext可获取方法参数、类名等信息,动态生成键值。

2. 流程引擎中的表达式

在Flowable流程引擎中,EL用于条件分支:

1
2
3
4
5
// 判断字符串截取结果
${variables:substr(a1,index1,end1) == '哈哈'}

// 检查集合包含元素
${c.contains("BCD")}

扩展能力
Flowable在Spring EL基础上支持自定义函数(如substr)。


四、常见问题与解决

1. 依赖冲突

  • 问题:缺少spring-expression依赖时,可能报错Unregistering JMX-exposed beans
  • 解决:检查Spring Boot版本(2.x+已内置EL支持),避免手动引入冲突依赖。

2. 表达式解析失败

  • 调试技巧:使用SpelExpressionParser手动解析:
1
2
3
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("#user.name");
String name = exp.getValue(context, String.class);

五、最佳实践

  1. 优先使用配置文件注入:将可变参数(如端口、路径)放在application.yml中,通过@Value("${}")读取。
  2. 避免复杂逻辑:EL表达式应保持简洁,复杂逻辑建议封装为Bean方法调用。
  3. 结合AOP实现动态功能:如缓存、日志等场景,通过EL动态拼接键值。

学习资源推荐

  • 官方文档:Spring Framework Expressions
  • 实战案例:Spring Security权限表达式