Spring EL表达式:架构师的秘密武器?

131 阅读4分钟

沉默是金,总会发光

大家好,我是沉默

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 个实战场景

  1. @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掉。