SpringBoot SpringEL表达式怎么使用
大家好,今天本人给大家带来文章《SpringBoot SpringEL表达式怎么使用》,文中内容主要涉及到,如果你对文章方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!
一、SpringEL-基础介绍
什么是SpringEL(SpEL)?
Spring3中引入了Spring表达式语言―SpringEL,SpEL是一种强大,简洁的装配Bean的方式
SpringEL可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中
SpringEL可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置
为什么要使用SpringEL?
平常通过配置文件或Annotaton注入的Bean,其实都可以称为静态性注入
如Bean A中有变量A,它的值需要根据Bean B的B变量为参考,在这场景下静态注入就对这样的处理显得非常无力
而Spring3增加的SpringEL就可以完全满足这种需求,而且还可以对不同Bean的字段进行计算再进行赋值,功能非常强大
如何使用SpringEL?
SpringEL从名字来看就能看出和EL是有点关系的,SpringEL的使用和EL表达式的使用非常相似
EL表达式在JSP页面更方便的获取后台中的值,而SpringEL就是为了更方便获取Spring容器中的Bean的值
EL使用${},而SpringEL使用#{}进行表达式的声明
两者主要区别
$是去找外部配置的参数,将值赋过来
#是SpEL表达式,去寻找对应变量的内容
也可以直接使用@value("常量")注入不使用EL,这样写法与直接赋值等价
如果是在Spring中使用可以使用**@PropertySource("classpath:my.properties")**加载对应配置文件
二、EL表达式-基础使用
# 配置文件 com: codecoord: el: num: 1001 name: el language: - java - spring - mysql - linux # 逗号分隔可以注入列表 language02: java,spring,mysql,linux
使用EL注入简单值
/**
* 注入简单值,直接注入不使用EL,EL不支持直接指定常量
* 直接在EL中指定的常量会当做配置处理,和直接赋值等价
*/
@Value("1432516744")
private Integer no;注入配置文件属性值
/**
* 注入整型属性值
*/
@Value("${com.codecoord.el.num}")
private Integer num;
/**
* 注入字符属性值
*/
@Value("${com.codecoord.el.name}")
private String name;注入默认值
/**
* 注入字符不存在属性值并指定默认值,默认值使用过冒号分隔 :
* 注入常量其实就可以指定一个不存在的配置然后使用默认值,此处skill的值为java
*/
@Value("${com.codecoord.el.skill:java}")
private String skill;注入列表
不支持直接配置文件中数组语法格式注入列表
可以识别使用逗号,分隔的配置,spring默认以,分隔
// 错误写法:不支持直接注入yml列表格式语法列表
@Value("${com.codecoord.el.language}")
private List listLanguage;
@Value("${com.codecoord.el.language}")
private String[] strLanguage; /**
* 支持,分隔的注入列表
*/
@Value("${com.codecoord.el.language02}")
private List listLanguage02;
@Value("${com.codecoord.el.language02}")
private String[] strLanguage02; 完整参考如下
配置文件
server: port: 8888 com: codecoord: el: num: 1001 name: el language: - java - spring - mysql - linux # 逗号分隔可以注入列表 language02: java,spring,mysql,linux
属性配置类
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
public class ElConfig {
/**
* 注入简单值,直接注入不使用EL,EL不支持直接指定常量
* 直接在EL中指定的常量会当做配置处理,和直接赋值等价
*/
@Value("1432516744")
private Integer no;
/**
* 注入整型属性值
*/
@Value("${com.codecoord.el.num}")
private Integer num;
/**
* 注入字符属性值
*/
@Value("${com.codecoord.el.name}")
private String name;
/**
* 注入字符不存在属性值并指定默认值,默认值使用过冒号分隔 :
* 注入常量其实就可以指定一个不存在的配置然后使用默认值,此处skill的值为java
*/
@Value("${com.codecoord.el.skill:java}")
private String skill;
/// 不支持直接注入列表
/*@Value("${com.codecoord.el.language}")
private List listLanguage;
@Value("${com.codecoord.el.language}")
private String[] strLanguage;*/
/**
* 支持,分隔的注入列表
*/
@Value("${com.codecoord.el.language02}")
private List listLanguage02;
@Value("${com.codecoord.el.language02}")
private String[] strLanguage02;
} 向controller中注入配置类,然后访问接口测试结果如下
{
"no": 1432516744,
"num": 1001,
"name": "el",
"skill": "java",
"listLanguage02": [
"java",
"spring",
"mysql",
"linux"
],
"strLanguage02": [
"java",
"spring",
"mysql",
"linux"
]
}三、SpringEL-基础使用
1、使用SpEL注入简单值和普通EL注入使用基本一致
2、SpEl注入map
配置文件中需要使用双引号括起来,否则将会注入失败,key为单引号
# SpEl
spEl:
mapInject: "{"name": "SpEl", "website": "http://www.codeocord.com"}"java类中先使用${spEl.mapInject}注入字符串值,#{}会解析字符串的值转为map
@Value("#{${spEl.mapInject}}")
private Map mapInject; 3、SpEl注入list
除了可以通过EL注入listI外,也可以使用#{${}.split("分隔符")}的方式注入List
配置文件中例如使用#分隔
spEl: listInject: "44#11#99#100"
java类中先使用${spEl.listInject}注入字符串值,内容使用单引号括起来,然后对字符串使用split方法分隔
提示:避免为空情况,可以给一个默认值空串
@Value("#{"${spEl.listInject:}".split("#")}")
private List listInject; 4、动态注入
上述注入都是静态注入,SpEl支持从Spring容器中注入信息,称为动态注入。动态注入类如下
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Data
public class SpElConstant {
private String name = "SpElConstant-name";
private String nickname = "tianxin";
private int num = 100;
private List product = new ArrayList() {{
add("huaweiMate30Pro");
add("xiaomi10x5g");
}};
private Map productMap = new HashMap() {{
put("huaweiMate30Pro", "5999");
put("xiaomi10x5g", "4999");
}};
private List cityList = new ArrayList() {{
add(new City("深圳", 1000L));
add(new City("杭州", 2000L));
add(new City("贵阳", 900L));
}};
public String showProperty() {
return "showProperty-无参数";
}
public String showProperty(String name) {
return "showProperty-" + name;
}
@Data
@AllArgsConstructor
static class City {
private String name;
private long population;
}
} SpEl支持和不支持操作
支持动态注入实例,类似于对象自动注入
SPL不支持直接注入配置文件中的配置
支持调用静态和实例方法
静态方法:@Value("#{T(package.ClassName).ConstFieldName")
支持调用静态类或常量
支持运算符运算
支持操作集合
支持查询筛选集合和投影
注入完整操作如下
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Data
@Component
public class SpElConfig {
/// 不支持直接注入配置文件值
/*@Value("#{com.codecoord.el.num}")
private Integer num;*/
/**
* 对象注入
*/
@Value("#{spElConstant}")
private SpElConstant spElConstant;
/**
* 注入ID为spElConstant Bean中的STR常量/变量
*/
@Value("#{spElConstant.name}")
private String name;
/**
* 调用无参方法
*/
@Value("#{spElConstant.showProperty()}")
private String method1;
/**
* 有参接收字符串的方法
*/
@Value("#{spElConstant.showProperty("Hell SpringEL")}")
private String method2;
/**
* 方法返回的String为大写
*/
@Value("#{spElConstant.showProperty().toUpperCase()}")
private String method3;
/**
* 若使用method3这种方式,若果showProperty返回为null
* 将会抛出NullPointerException,可以使用以下方式避免
* 使用?.符号代表若然左边的值为null,将不执行右边方法
*/
@Value("#{spElConstant.showProperty()?.toUpperCase()}")
private String method4;
/**
* 注入math常量
*/
@Value("#{T(java.lang.Math).PI}")
private double pi;
/**
* 用random方法获取返回值
*/
@Value("#{T(java.lang.Math).random()}")
private double random;
/**
* 获取文件路径符号
*/
@Value("#{T(java.io.File).separator}")
private String separator;
/**
* 拼接字符串
*/
@Value("#{spElConstant.nickname + " " + spElConstant.name}")
private String concatString;
/**
* 对数字类型进行运算,spElConstant拥有num属性
*/
@Value("#{3 * T(java.lang.Math).PI + spElConstant.num}")
private double operation;
/**
* 进行逻辑运算
*/
@Value("#{spElConstant.num > 100 and spElConstant.num <= 200}")
private boolean logicOperation;
/**
* 进行或非逻辑操作
*/
@Value("#{not (spElConstant.num == 100) or spElConstant.num <= 200}")
private boolean logicOperation2;
/**
* 使用三元运算符
*/
@Value("#{spElConstant.num > 100 ? spElConstant.num : spElConstant.num + 100}")
private Integer logicOperation3;
/**
* 获取下标为0的元素
*/
@Value("#{spElConstant.product[0]}")
private String str;
/**
* 获取下标为0元素的大写形式
*/
@Value("#{spElConstant.product[0]?.toUpperCase()}")
private String upperStr;
/**
* 获取map中key为hello的value
*/
@Value("#{spElConstant.productMap["hello"]}")
private String mapValue;
/**
* 根据product下标为0元素作为key获取testMap的value
*/
@Value("#{spElConstant.productMap[spElConstant.product[0]]}")
private String mapStrByproduct;
/**
* 注入人口大于等于1000人口的城市
*/
@Value("#{spElConstant.cityList.?[population >= 1000]}")
private List cityList;
/**
* 注入人口等于900人口的城市
*/
@Value("#{spElConstant.cityList.?[population == 900]}")
private SpElConstant.City city;
/**
* 注入人口大于等于1000人口的城市,且只保留城市名称
*/
@Value("#{spElConstant.cityList.?[population >= 1000].![name]}")
private List cityName;
} 注入结果
{
"spElConstant": {
"name": "SpElConstant-name",
"nickname": "tianxin",
"num": 100,
"product": [
"huaweiMate30Pro",
"xiaomi10x5g"
],
"productMap": {
"xiaomi10x5g": "4999",
"huaweiMate30Pro": "5999"
},
"cityList": [
{
"name": "深圳",
"population": 1000
},
{
"name": "杭州",
"population": 2000
},
{
"name": "贵阳",
"population": 900
}
]
},
"name": "SpElConstant-name",
"method1": "showProperty-无参数",
"method2": "showProperty-Hell SpringEL",
"method3": "SHOWPROPERTY-无参数",
"method4": "SHOWPROPERTY-无参数",
"pi": 3.141592653589793,
"random": 0.19997238292235787,
"separator": "",
"concatString": "tianxin SpElConstant-name",
"operation": 109.42477796076938,
"logicOperation": false,
"logicOperation2": true,
"logicOperation3": 200,
"str": "huaweiMate30Pro",
"upperStr": "HUAWEIMATE30PRO",
"mapValue": null,
"mapStrByproduct": "5999",
"cityList": [
{
"name": "深圳",
"population": 1000
},
{
"name": "杭州",
"population": 2000
}
],
"city": {
"name": "贵阳",
"population": 900
},
"cityName": [
"深圳",
"杭州"
]
}Spring操作外部Properties文件
public class TestSpringEL {
// 注意db为xml文件中声明的id
@Value("#{db["jdbc.url"]}")
private String propertiesValue;
}SpringEL在使用时仅仅是一个字符串,不易于排错与测试,也没有IDE检查我们的语法,当出现错误时较难检测,复杂的表达式不建议通过SpringEL方式注入。在非必要情况下,不推荐使用SpEl的复杂注入,清晰可读的代码更为重要且有利于排查问题
四、属性自动注入
上述都是通过指定字段进行注入,可以通过@ConfigurationProperties指定前缀进行自动注入
org.springframework.boot.context.properties.ConfigurationProperties
配置类
user:
id: ${random.uuid}
name: autowire
address: unknown
website: www.codecoord.com
age: ${random.int}自动属性注入类
通过prefix指定前端为user,然后将会把user.后的类型按照名称进行注入
注意必须要提供setter方法
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "user")
@Data
public class UserConfig {
private String id;
private String name;
private String address;
private String website;
private Integer age;
}可以通过@EnableConfigurationProperties(value = UserConfig.class)将UserConfig再次强制注入,问题出现在如果UserConfig为第三方jar包内的配置类,则可能出现属性没有注入情况,所以可以指定注入
好了,本文到此结束,带大家了解了《SpringBoot SpringEL表达式怎么使用》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!
如何解决海康威视SADPTool因缺失MSVCR120.dll导致的报错问题
- 上一篇
- 如何解决海康威视SADPTool因缺失MSVCR120.dll导致的报错问题
- 下一篇
- Go Kafka `ProduceChannel()` 填满并挂起
-
- 文章 · java教程 | 1天前 | Java教程 · TTL缓存 · ConcurrentHashMap · 小项目 · java 本地缓存 concurrenthashmap TTL缓存 过期淘汰
- Java 本地 TTL 缓存小项目:用 ConcurrentHashMap 实现过期淘汰和命中统计
- 394浏览 收藏
-
- 文章 · java教程 | 1天前 | Java · Stream · 数据处理 · 后端教程 · Java Stream bigdecimal 分组统计 Collectors 订单汇总
- Java Stream 分组统计实验:从订单列表到客户消费汇总
- 355浏览 收藏
-
- 文章 · java教程 | 1天前 | Java · Spring Boot · 后端开发 · 接口校验 · java spring boot dto 接口设计 参数校验
- Spring Boot 参数校验工作流:DTO、注解和统一错误响应
- 495浏览 收藏
-
- 文章 · java教程 | 1星期前 | map · 并发安全 · 缓存设计 · Java教程 · java optional concurrenthashmap computeIfAbsent Map缓存
- Java computeIfAbsent 缓存初始化实战:少写判断、避开空值和并发坑
- 236浏览 收藏
-
- 文章 · java教程 | 1星期前 | Java · 异步编程 · 后端开发 · CompletableFuture · 接口聚合 · java 结果合并 completablefuture 并行调用 超时兜底
- Java CompletableFuture 多接口聚合完整流程:并行调用、超时兜底和结果合并
- 428浏览 收藏
-
- 文章 · java教程 | 1星期前 | Java · 线程安全 · DateTimeFormatter · 日期处理 · 并发问题 · java 线程安全 日期格式化 threadlocal SimpleDateFormat DateTimeFormatter
- Java SimpleDateFormat 日期偶发错乱怎么办:从共享实例到线程安全一步步排查
- 481浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ljg-skills
- ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
- 2672次使用
-
- MELO音乐
- MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
- 2472次使用
-
- UniScribe
- UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
- 2413次使用
-
- 剧云
- 剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
- 2643次使用
-
- 万象有声
- 万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
- 2591次使用
-
- 矩阵主副对角线快速定位技巧
- 2026-05-31 501浏览
-
- Java多态优化流程代码与行为分发改进
- 2026-05-26 501浏览
-
- JVM 类元数据双亲委派链表深度解析
- 2026-05-21 501浏览
-
- 反射异常处理:InvocationTargetException解析与应用
- 2026-05-16 501浏览
-
- 怎么通过 HTML 的 accesskey 属性为网页中的按钮或链接设置键盘快捷键
- 2026-05-04 501浏览

