spring通过spel(#{...})支持动态解析配置属性,常用于@value、@conditionalonexpression等场景,可结合环境变量、系统属性、静态方法及bean调用实现默认值、类型转换和条件逻辑。

Spring 通过 SpEL(Spring Expression Language)支持在配置文件中动态解析属性值,主要用在 @Value 注解、@ConditionalOnExpression、XML 配置或 @ConfigurationProperties 绑定过程中。关键在于使用 #{...} 语法包裹 SpEL 表达式,并确保上下文能访问到所需变量(如环境属性、Bean、静态方法等)。
在 @Value 中使用 SpEL 解析配置属性
这是最常见场景:从 application.properties 或 application.yml 读取基础值,再用 SpEL 做转换、默认值兜底或条件拼接。
- 用
${...}获取原始配置项,用#{...}执行 SpEL 运算 - 支持调用
System.getProperty()、System.getenv()、Ternary 操作符、字符串方法等 - 示例:
application.propertiesapp.env=prod<br>app.port=8080
Java 类中@Value("#{systemProperties['user.home'] + '/logs/' + '${app.env:dev}' + '-app.log'}")<br>private String logPath;
→ 若系统属性user.home=/home/user,且未设置app.env,则值为/home/user/logs/dev-app.log
结合 Environment 和 PropertySource 动态计算
SpEL 表达式可直接引用 Spring 的 environment 对象,获取并处理任意配置属性,包括 profile 相关值。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
#{environment.getActiveProfiles()[0] ?: 'default'}—— 获取第一个激活的 profile,无则用 default -
#{environment.getProperty('app.timeout', '30', int.class)}—— 带类型转换和默认值 @Value("#{environment.containsProperty('app.debug') && environment.getProperty('app.debug').toBoolean() ? 'DEBUG' : 'INFO'}")<br>private String logLevel;
调用静态工具方法或 Bean 方法
SpEL 支持调用静态方法(用 T(...).method())或容器中已注册的 Bean(用 @beanName.method()),适合复用逻辑。
- 调用静态方法:
@Value("#{T(java.lang.Math).max(${app.min.port}, 8080)}") private int serverPort; - 调用 Bean 方法(假设存在
@Component class ConfigHelper):@Value("#{@configHelper.buildEndpoint('${app.host}', ${app.port})}") private String endpoint; - 注意:被调用的 Bean 必须已初始化(非懒加载且无循环依赖),否则启动报错
在 @ConfigurationProperties 中间接使用 SpEL(有限支持)
@ConfigurationProperties 本身不直接解析 SpEL,但可通过构造器注入或 @PostConstruct 阶段结合 ConfigurableEnvironment 补充计算。
- 推荐方式:用
@Value注入 SpEL 计算结果到字段,再在@PostConstruct中赋给配置类属性 - 或自定义
PropertyEditor/Converter实现运行时解析(较重,一般不必要) - 避免在
@ConfigurationProperties字段上直接写@Value("#{...}")—— 不生效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










