什么是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操作集合

```java

```java
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检查我们的语法,当出现错误时较难检测

 

总结:

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

SpringEl表达式(转)的更多相关文章

  1. JavaEE开发之Spring中Bean的作用域、Init和Destroy方法以及Spring-EL表达式

    上篇博客我们聊了<JavaEE开发之Spring中的依赖注入以及AOP>,本篇博客我们就来聊一下Spring框架中的Bean的作用域以及Bean的Init和Destroy方法,然后在聊一下 ...

  2. 👊 Spring技术原理系列-从零开始教你SpringEL表达式使用和功能分析讲解指南(上篇)

    Spring EL表达式语言,这种语言jsp中学到的el,但是在整个spring之中其表达式语言要更加的复杂,而且支持度更加的广泛,最重要的是他可以进行方法的调用,对象的实例化,集合操作等等,但是唯一 ...

  3. SpringEl表达式解析

    应用场景: 1.用户日志 2.缓存处理 3........... import org.springframework.expression.EvaluationContext; import org ...

  4. SpringEL 表达式错误记录

    原因暂时未知....

  5. (二)Thymeleaf标准表达式之——简单表达式

    2. 标准表达式(Standard Expression Syntax) 标准表达式包含以下几个方面: 简单表达式: 变量表达式: ${...} 选择变量表达式: *{...} 消息表达式: #{.. ...

  6. Thymeleaf+SpringMVC,如何从模板中获取数据

    Thymeleaf+SpringMVC,如何从模板中获取数据 在一个典型的SpringMVC应用中,带@Controller注解的类负责准备数据模型Map的数据和选择一个视图进行渲染.这个模型Map对 ...

  7. Thymeleaf+Spring整合

    前言 这个教程介绍了Thymeleaf与Spring框架的集成,特别是SpringMvc框架. 注意Thymeleaf支持同Spring框架的3.和4.版本的集成,但是这两个版本的支持是封装在thym ...

  8. spring缓存

    Spring Cache使用详解   复制过来时的地址:http://blog.csdn.net/xiaoyu411502/article/details/48901555 标签: spring-bo ...

  9. Spring Security3学习实例

    Spring Security是什么? Spring Security,这是一种基于Spring AOP和Servlet过滤器的安全框架.它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理 ...

随机推荐

  1. Netty基础系列(1) --linux网路I/O模型

    引言 我一直认为对于java的学习,掌握基础的性价比要远远高于使用框架,而基础知识中对于网络相关知识的掌握也是重中之重.对于一个java程序来说,无论是工作中还是面试,对于Netty的掌握都是及其重要 ...

  2. PCA与LDA介绍

    PCA(主成分分析) PCA是一种无监督降维方式,它将数据投影到一组互相正交的loading vectors(principal axes)之上,并保证投影后的点在新的坐标轴上的方差最大 记数据集\( ...

  3. sau交流学习社区--songEagle开发系列:Vue.js + Koa.js项目中使用JWT认证

    一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...

  4. vue项目使用websocket技术

    一.为什么需要websocket? 前端和后端的交互模式最常见的就是前端发数据请求,从后端拿到数据后展示到页面中.如果前端不做操作,后端不能主动向前端推送数据,这也是http协议的缺陷. 因此,一种新 ...

  5. POLARDB · 最佳实践 · POLARDB不得不知道的秘密

    ## 前言 POLARDB作为阿里云下一代关系型云数据库,自去年9月份公测以来,收到了不少客户的重点关注,今年5月份商业化后,许多大客户开始陆续迁移业务到POLARDB上,但是由于POLARDB的很多 ...

  6. python之循序渐进学习装饰器

    python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  7. 如何高效的学习WEB前端

    IT 行业的变化快是众人皆知的,需要持续去学习新的知识内容.但是,往往我们工作之后,经常发现学习的东西很少了,学习效率非常低,感觉自己到了一个瓶颈期,久而久之,就演变成『一年工作经验,重复去用十年』的 ...

  8. SAP MM 巴西采购订单中的NCM Code

    SAP MM 巴西采购订单中的NCM Code 1,近日收到业务部门报的一个问题,某用户试图将采购订单4400000071中ITEM 40的删除标记取消, SAP系统报错,'Enter a valid ...

  9. 关于web资金系统提现安全保护,防止极快的重复并发请求导致重复提现的解决思路

    关于WEB金融系统中的提现安全问题很多人没有深入思想,导致有漏洞,常常会遇到有些人遇到被攻击到导资金损失的麻烦,     其实要彻底解决重复并发请求 导致重复提现问题,是需要花点心思的,并没有看起来的 ...

  10. windows dll的def文件

    DLL(testcase_1.dll )源码:myfun.h #pragma once #ifdef TESTCASE_1_EXPORTS #define MY_API __declspec(dlle ...