基于springEL表达式详解及应用

目录
  • 基于springEL表达式详解及应用
    • 什么是SpringEL?
    • 为什么要使用SpringEL?
    • 如何使用SpringEL?
    • 使用SpringEL注入简单值
    • 使用SpringEL调用方法
    • SpringEL调用静态类或常量
    • SpringEL运算
    • SpringEL使用正则表达式
    • SpringEL操作集合
    • Spring操作外部Properties文件
    • 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,适当的技术方在适当的位置,才能更好的完成事情。

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

(0)

相关推荐

  • springboot Quartz动态修改cron表达式的方法

    1.概述: 在开发中有的时候需要去手动禁止和启用定时任务,修改定时任务的cron表达式然后再让其动态生效,之前有过SSM的类似的业务的开发但是忘记写下来了...只好重新温习了一次,加上最近比较流行springBoot所以升级了一下用springBoot来完成. 2.关联技术 SpringBoot.Quartz.H2.thymeleaf (好像就这么多) 3.具体流程 1)首先去手动创建一个调度器工厂对象-SchedulerFactoryBean;其实应该不用手动创建的但是为了顾及到业务的复杂性所

  • SpringBoot 调度任务及常用任务表达式

    1.首先需要用@EnableScheduling注解到*applicatin.java,用来检测是否有调度任务. 2.@Scheduled 注解用于标注这个方法是一个定时任务的方法.Spring会自动扫描这个注解,启动调度任务. package com.david.translate.quartz; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.schedulin

  • SpringBoot SpringEL表达式的使用

    目录 一.SpringEL-基础介绍 二.EL表达式-基础使用 三.SpringEL-基础使用 四.属性自动注入 一.SpringEL-基础介绍 什么是SpringEL(SpEL)? Spring3中引入了Spring表达式语言-SpringEL,SpEL是一种强大,简洁的装配Bean的方式 SpringEL可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中 SpringEL可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置 为什么要使用SpringEL? 平

  • 基于springEL表达式详解及应用

    目录 基于springEL表达式详解及应用 什么是SpringEL? 为什么要使用SpringEL? 如何使用SpringEL? 使用SpringEL注入简单值 使用SpringEL调用方法 SpringEL调用静态类或常量 SpringEL运算 SpringEL使用正则表达式 SpringEL操作集合 Spring操作外部Properties文件 SpringEL查询筛选集合和投影 优点: 缺点: 笔者实际应用: 总结: 基于springEL表达式详解及应用 什么是SpringEL? Spri

  • 基于JSON数据格式详解

    JSON是行业内使用最为广泛的数据交换格式,在很多场景都有广泛的应用.JSON适用于进行数据交互的场景,典型的是Ajax中实现异步加载:为了支持跨平台.数据安全等的Web Service也可以使用(API接口返回值). JSON(JavaScript Object Notation)是一种完全独立于语言的.轻量级的数据交换格式.它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子

  • re模块的正则匹配的表达式详解

    一.校验数字的表达式 1.数字 ^[0-9]\*$ 2.n位的数字 ^\d{n}$ 3.至少n位的数字 ^\d{n,}$ 4.m-n位的数字 ^\d{m,n}$ 5.零和非零开头的数字 ^(0|[1-9][0-9]\*)$ 6.非零开头的最多带两位小数的数字 ^([1-9][0-9]\*)+(\.[0-9]{1,2})?$ 7.带1-2位小数的正数或负数 ^(\-)?\d+(\.\d{1,2})$ 8.正数.负数.和小数 ^(\-|\+)?\d+(\.\d+)?$ 9.有两位小数的正实数 ^[0

  • 基于YUV 数据格式详解及python实现方式

    YUV 数据格式概览 YUV 的原理是把亮度与色度分离,使用 Y.U.V 分别表示亮度,以及蓝色通道与亮度的差值和红色通道与亮度的差值.其中 Y 信号分量除了表示亮度 (luma) 信号外,还含有较多的绿色通道量,单纯的 Y 分量可以显示出完整的黑白图像.U.V 分量分别表示蓝 (blue).红 (red) 分量信号,它们只含有色彩 (chrominance/color) 信息,所以 YUV 也称为 YCbCr,C 意思可以理解为 (component 或者 color). 维基百科上的 RGB

  • 阿里云OSS基于java使用详解

    近几年,云图片服务器五花八门,越来越多,有腾讯云,阿里云,又拍云,华为云等等,但是使用了这么多年,我还是感觉阿里云图片服务器oss比较稳定,访问速度也比较快,因此我在这里手把手教给你如何使用阿里云oss服务: 一.使用之前,我们还是先来搞清楚阿里云oss使用的原理吧: 其实调用方式也就两种,一种是直接客户端调用阿里云提供的服务器进行上传,一种是通过服务器间接上传,我们来分析以下优缺点吧: 上传方式优点缺点直接调用上传速度快,能直接快速上传到阿里云服务器,不需要中转可能会不安全,暴露核心配置信息间

  • jsp EL表达式详解

    一.EL表达式介绍 Expression Language表达式语言 是一种在JSP页面获取数据的简单方式(只能获取数据,不能设置数据) 在JSP2.0开始引入概念 语法格式 在JSP页面的任何静态部分均可通过:${expression}来获取到指定表达式的值 二.EL获取数据(从四大域中获取属性) EL只能从四大域中获取属性 1.如果没有使用EL的内置对象,则查找数据顺序是依次按照由小到大范围从四大域中查找指定名称的属性值 二.EL获取数据(从四大域中获取属性) EL只能从四大域中获取属性 1

  • python3 lambda表达式详解

    技术背景 lambda表达式本身是一个非常基础的python函数语法,其基本功能跟使用def所定义的python函数是一样的,只是lambda表达式基本在一行以内就完整的表达了整个函数的运算逻辑.这里我们简单展示一些lambda表达式的使用示例,以供参考. 二元求和 首先我们尝试一个最简单的二元求和的ipython案例,输入两个参数x和y,返回这两个元素的和: [dechin@dechin-manjaro 2021-python]$ ipython Python 3.8.5 (default,

  • C++实现中缀表达式转化为后缀表达式详解

    目录 1.题目描述 2.输入输出 3.解题思路 4.样例解析 5.代码实现 5.1.优先级确认 5.2.转换函数 1.题目描述 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右进行(不用考虑运算符的优先级). 如:中缀表达式 3*(5–2)+7 对应的后缀表达式为:352-*7+ . 请将给出的中缀表达式转化为后缀表达式并输出. 2.输入输出 输入样例: 2+4*8+(8*8+1)/3 输出样例: 248*+88*1

  • C++函数对象Functor与匿名函数对象Lambda表达式详解

    目录 1函数对象Functor(仿函数) 1.1概念 1.2代码实例 1.3调用效率 2.匿名函数对象Lambda表达式 2.1使用形式 2.2代码实例 3总结 1函数对象Functor(仿函数) 1.1概念 函数对象就是类对象,生成这个类对象的类中,拥有一个小括号运算符重载函数. 重载了小括号运算符的类的类对象,就叫函数对象. 1.2代码实例 #include <iostream> using namespace std; template <class T1> class A

  • C++ Boost Lambda表达式详解

    目录 lambda表达式格式 说明Boost.Lambda lambda表达式格式 lambda表达式的格式 [捕捉列表](参数列表)mutable->返回值类型{ 语句部分 }; 其中参数列表.返回值类型是可选的,捕捉列表.函数体可以为空. 先来看一个较为简单的lamda表达式 int main(void) { auto add = [](int a, int b)->int {return a + b; }; cout << add(1, 2) << endl; r

随机推荐