沉默是金,总会发光
大家好,我是沉默
SpEL(Spring Expression Language)是架构师的“秘密武器”,灵活、高效、功能强大,能在 Bean 注入、条件配置、AOP、配置解耦里“一语惊人”。
本文带你深入理解 SpEL 到底是啥?语法怎么样? 怎么用才高级?有什么坑?
**-**01-
SpEL 是什么?
SpEL(Spring Expression Language)是 Spring 提供的一套 运行时表达式求值语言,就像是为你的配置、注解、切面等加上了“计算能力”。
可以:
-
用它读取对象属性:
#{user.name} -
调用方法、执行逻辑:
#{user.age > 18 ? '成年人' : '未成年'} -
动态控制 Bean 创建、注入、AOP 拦截、配置计算…
为什么 SpEL 是 架构师的秘密武器?
因为 SpEL 的设计,就是为了解决这类问题:
“我想根据配置值决定一个 Bean 的属性。”
“我想读取系统环境变量用于自动配置。”
“我想只在某些平台下启用某段配置。”
“我希望注解参数支持动态逻辑。”
如果你只会 @Value("${}"),那你用的只是 SpEL 的 10%。它其实是一个 具备完整语法、能处理对象图、条件表达式、方法调用、集合过滤的 mini 脚本引擎。
**-**02-
SpEL 语法秒懂
基础用法一览(掌握 80% 的场景)
| 功能
|
示例表达式
|
含义
| | --- | --- | --- | |
访问属性
| #{user.name} |
访问 user 对象的 name
| |
调用方法
| #{user.getAge()} |
调用方法
| |
算术运算
| #{5 + 3} |
基础运算
| |
条件判断
| #{user.age > 18} |
布尔表达式
| |
访问 List
| #{list[0]} |
取第一个元素
| |
Map 访问
| #{map['key']} |
取指定键值
| |
Bean 引用
| #{@beanName} |
引用容器中的 Bean
| |
静态方法
| #{T(java.lang.Math).random()} |
调用静态类
|
进阶语法:集合过滤与投影
# 过滤:找出年龄 > 18 的用户#{users.?[age > 18]}# 投影:提取所有用户的姓名#{users.![name]}
是不是和 SQL 有点像?这就是它上手快的秘诀:类 SQL 思维,面向对象操作。
**-**03-
常见的 4 个实战场景
@Value动态注入配置 & 系统值
@Value("#{systemProperties['os.name']}")
private String osName;
@Value("#{10 * 2}")
private int calculated;
用法场景: 配置计算、环境感知、默认值兜底等。
2. 条件化 Bean 创建(配合 @ConditionalOnExpression)
@Configuration
@ConditionalOnExpression("#{systemProperties['os.name'].contains('Windows')}")
public class WindowsOnlyConfig {}
用法场景: Windows 和 Linux 不同配置、Dev/Prod 环境切换。
3. 在 XML 配置中使用 SpEL
<property name="timeout" value="#{T(java.lang.Math).max(5, 10)}"/>
用法场景: 计算属性、配置依赖值、避免硬编码。
4. AOP 切点表达式增强
@Pointcut("execution(* com.example..*Service.*(..)) && @annotation(tx)")
public void transactionalServiceMethods() {}
虽然 SpEL 不是在表达式里直接用,但配合注解、上下文信息的动态求值也是它的能力体现。
**-**04-
SpEL 的注意事项
SpEL 不止写法巧,它还能连接系统上下文
-
Bean 引用:
#{@myService.doSomething()}引用 Bean 并调用方法 -
静态引用:
#{T(java.lang.Math).abs(-5)}调用类静态方法 -
集合处理:
#{users.?[age > 18].![name]}条件筛选并映射属性 -
安全导航(避免空指针):
#{user?.name}类似 Kotlin 的安全调用
踩坑指南
| 风险点
|
应对方法
| | --- | --- | |
表达式出错 -> 应用启动失败
|
启动前校验,IDE 提示可用
| |
NullPointerException
|
使用 ?. 安全导航
| |
性能问题(频繁求值)
|
简化表达式 or 缓存中间结果
| |
不易调试
|
保持表达式简洁、可读,日志中打印求值结果
|
总结
SpEL 不是装饰性的语法,而是 Spring 灵活配置与动态行为的内核机制之一。
掌握它,你就能在配置、Bean 注入、AOP、环境切换等多种复杂场景中游刃有余。特别是在微服务、配置中心、自动化部署中,SpEL 往往是让系统“智能化”的关键。
**-**05-
粉丝福利
我这里创建一个程序员成长&副业交流群,和一群志同道合的小伙伴,一起聚焦自身发展,可以聊:技术成长与职业规划,分享路线图、面试经验和效率工具,探讨多种副业变现路径,从写作课程到私活接单,主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。如果你对这个特别的群,感兴趣的,可以加一下,微信通过后会拉你入群,但是任何人在群里打任何广告,都会被我T掉。