基于springEL表达式详解及应用

 更新时间:2021年08月20日 09:24:42   作者:青鱼入云  
这篇文章主要介绍了springEL表达式详解及应用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

基于springEL表达式详解及应用

什么是SpringEL?

Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,更可以调用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使用#{}进行表达式的声明。

使用SpringEL注入简单值

public class TestSpringEL {
 
 /*
  * @Value注解等同于XML配置中的<property/>标签, 
  * SpringEL同样支持在XML<property/>中编写
 */
 
 // 注入简单值,输出num为5
 @Value("#{5}")
 
 private Integer num;
 
 // 注入ID为testConstant的Bean
 @Value("#{testConstant}")
 
 private TestConstant Constant;
 
 // 注入ID为testConstant Bean中的STR常量/变量
 @Value("#{testConstant.STR}")
 private String str;
}

使用SpringEL调用方法

public class TestSpringEL {
 
 /*
  * TestConstant类中有两个方法重载,
  * 返回值为String类型
 */
 
 // 调用无参方法
 @Value("#{testConstant.showProperty}")
 private String method1;
 
 // 有参接收字符串的方法
 @Value("#{testConstant.showProperty('Hello')}")
 private String method2;
 
 /*
  * 若然希望方法返回的String为大写
 */
 @Value("#{testConstant.showProperty().toUpperCase()}")
 private String method3;
 
 /*
  * 若使用method3这种方式,若然showProperty返回为null, 
  * 将会抛出NullPointerException,可以使用以下方式避免
 */
 @Value("#{testConstant.showProperty()?.toUpperCase}")
 private String method4;
 
 /*
  * 使用?.符号代表若然左边的值为null,将不执行右边方法, 
  * 读者可以灵活运用在其他场景,只要左边可能返回null,
  * 即可使用上面示例中的?.
 */
}

SpringEL调用静态类或常量

public class TestSpringEL {
 /*
  * 注入JDK中的工具类常量或调用工具类的方法
 */
 
 // 获取Math的PI常量
 @Value("#{T(java.lang.Math).PI")
 private double pi;
 
 // 调用random方法获取返回值
 @Value("#{T(java.lang.Math).random()}")
 private double ramdom;
 
 // 获取文件路径符号
 @Value("#{T(java.io.File).separator}")
 private String separator;
}

SpringEL运算

public class TestSpringEL {
 /*
  * 使用SpringEL进行运算及逻辑操作
 */
 
 // 拼接字符串
 @Value("#{testConstant.nickname + ' ' + testConstant.name}")
 private String concatString;
 
 // 对数字类型进行运算,testConstant拥有num属性
 @Value("#{ 3 * T(java.lang.Math).PI + testConstant.num}")
 private double operation;
 
 // 进行逻辑运算
 @Value("#{testConstant.num > 100 and testConstant.num <= 200}")
 private boolean logicOperation;
 
 // 进行或非逻辑操作
 @Value("#{ not testConstant.num == 100 or testConstant.num <= 200}")
 private boolean logicOperation2;
 
 // 使用三元运算符
 @Value("#{testConstant.num > 100 ? testConstant.num : testConstant.num + 100}")
 private Integer logicOperation3;
}

SpringEL使用正则表达式

public class TestSpringEL {
 // 验证是否邮箱地址正则表达式
 @Value("#{testConstant.STR match '\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+'}")
 private boolean regularExpression;
}

SpringEL操作集合

public class TestSpringEL {
 /*
  * TestConstant类中拥有名为testList的List变量, 和名为testMap的Map
 */
 
 // 获取下标为0的元素
 @Value("#{testConstant.testList[0]}")
 private String str;
 
 // 获取下标为0元素的大写形式
 @Value("#{testConstant.testList[0]?.toUpperCase()}")
 private String upperStr;
 
 // 获取map中key为hello的value
 @Value("#{testConstant.testMap['hello']}")
 private String mapValue;
 
 // 根据testList下标为0元素作为key获取testMap的value
 @Value("#{testConstant.testMap[testConstant.testList[0]]}")
 private String mapStrByTestList;
}

Spring操作外部Properties文件

<!-- 首先通过applicaContext.xml中<util:properties>增加properties文件 -->
<!-- 注意需要引入Spring的util schemea命名空间和注意id属性,id属性将在SpringEL中使用 -->
<util:properties id="test" location="classpath:application.properties"/>
public class TestSpringEL {
 // 注意test为xml文件中声明的id
 @Value("#{test['jdbc.url']}")
 private String propertiesValue;
}

SpringEL查询筛选集合和投影

public class TestSpringEL {
 /*
  * 声明City类,有population属性 testContants拥有名叫cityList的City类List集合
 */
 
 // 过滤testConstant中cityList集合population属性大于1000的全部数据注入到本属性
 @Value("#{testConstant.cityList.?[population > 1000]}")
 private List<City> cityList;
 
 // 过滤testConstant中cityList集合population属性等于1000的第一条数据注入到本属性
 @Value("#{testConstant.cityList.^[population == 1000]}")
 private City city;
 
 // 过滤testConstant中cityList集合population属性小于1000的最后一条数据注入到本属性
 @Value("#{testConstant.cityList.$[population < 1000]}")
 private City city2;
 
 /*
  * 首先为city增加name属性,代表城市的名称
 */
 
 /*
  * 假如我们在过滤城市集合后只想保留城市的名称,
  * 可以使用如下方式进行投影
 */
 @Value("#{testConstant.cityList.?[population > 1000].![name]}")
 private List<String> cityName;
}

优点:

SpringEL功能非常强大,在Annotation的方式开发时可能感觉并不强烈,因为可以直接编写到源代码来实现SpringEL的功能,但若然是在XML文件中进行配置,SpringEL可以弥补XML静态注入的不足,从而实现更强大的注入

缺点:

SpringEL在使用时仅仅是一个字符串,不易于排错与测试,也没有IDE检查我们的语法,当出现错误时较难检测

笔者实际应用:

笔者开发的项目当中比较频繁的使用SpringEL,例如通过SpringEL获取外部properties中的值,又或者项目当中的数据字典亦是使用SpringEL的一个场景,我们抽象出一个Param类的集合,通过SpringEL集合筛选和投影获取我们想要的字段参数添加到我们的程序逻辑当中(笔者项目中的Spring Security亦使用SpringEL,但本文章不加以叙述)

总结:

Spring3.0让人为之惊艳的非SpringEL莫属,为我们的注入提供了另一种强大的形式,传统注入能做到的事情,和做不到的事情,SpringEL一概能完成,但在项目当中并不适宜大量使用SpringEL,适当的技术方在适当的位置,才能更好的完成事情。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现简易五子棋小游戏

    Java实现简易五子棋小游戏

    这篇文章主要为大家详细介绍了Java实现简易五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • java读写excel文件实现POI解析Excel的方法

    java读写excel文件实现POI解析Excel的方法

    在日常工作中,我们常常会进行Excel文件读写操作,这篇文章主要介绍了java读写excel文件实现POI解析Excel的方法,实例分析了java读写excel的技巧,非常具有实用价值,需要的朋友可以参考下
    2018-10-10
  • Java实现CSV格式转对象

    Java实现CSV格式转对象

    csv全称“Comma-Separated Values”,是一种逗号分隔值格式的文件,常用来存储数据的纯文本格式文件。本文将用Java语言实现CSV转对象,需要的可以参考一下
    2022-06-06
  • 详解spring cloud config实现datasource的热部署

    详解spring cloud config实现datasource的热部署

    这篇文章主要介绍了详解spring cloud config实现datasource的热部署,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 源码分析Spring 中 @Qualifier 注解基本用法

    源码分析Spring 中 @Qualifier 注解基本用法

    这篇文章主要介绍了源码分析Spring 中 @Qualifier 注解基本用法,在源码分析的过程中,也 GET 到 Spring 许多新的玩法,感兴趣的小伙伴赶紧去试试吧
    2023-08-08
  • java实现潜艇大战游戏源码

    java实现潜艇大战游戏源码

    潜艇大战游戏相信大家都玩过,是一款非常有趣的小游戏,那么基于代码是如何实现的呢?今天小编给大家带来一篇教程帮助大家学习java实现潜艇大战游戏,感谢的朋友一起看看吧
    2021-06-06
  • Idea 快速生成方法返回值的操作

    Idea 快速生成方法返回值的操作

    这篇文章主要介绍了Idea 快速生成方法返回值的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Intellij IDEA实现SpringBoot项目多端口启动的两种方法

    Intellij IDEA实现SpringBoot项目多端口启动的两种方法

    有时候使用springboot项目时遇到这样一种情况,用一个项目需要复制很多遍进行测试,除了端口号不同以外,没有任何不同。遇到这种情况怎么办呢?这时候可以使用Intellij IDEA解决
    2018-06-06
  • Mybatis Plus 实现批量插入的示例代码

    Mybatis Plus 实现批量插入的示例代码

    本文主要介绍了Mybatis Plus 实现批量插入的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Java算法之BFS,DFS,动态规划和贪心算法的实现

    Java算法之BFS,DFS,动态规划和贪心算法的实现

    广度优先搜索(BFS)和深度优先搜索(DFS)是图遍历算法中最常见的两种算法,主要用于解决搜索和遍历问题。动态规划和贪心算法则用来解决优化问题。本文就来看看这些算法的具体实现吧
    2023-04-04

最新评论