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调⽤⽅法
/*
* TestConstant类中有两个⽅法重载,
* 返回值为String类型
*/
// 调⽤⽆参⽅法
@Value("#{testConstant.showProperty}")
private String method1;
// 有参接收字符串的⽅法
el表达式获取值
@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运算
/*
* 使⽤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("#{stList[0]}")
private String str;
// 获取下标为0元素的⼤写形式
@Value("#{stList[0]?.toUpperCase()}")
private String upperStr;
// 获取map中key为hello的value
@Value("#{stMap['hello']}")
private String mapValue;
// 根据testList下标为0元素作为key获取testMap的value
@Value("#{stList[0]]}")
private String mapStrByTestList;
}
Spring操作外部Properties⽂件
<!-- ⾸先通过l中<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,适当的技术⽅在适当的位置,才能更好的完成事情

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。