Spring框架学习--基础的SPEL表达式

版权声明:本文为博主原创文章,未经博主允许转载,写明链接即盗版不究。 https://blog.csdn.net/xjmchris03/article/details/81585070

Spring 3引入了Spring表达式语言(Spring Expression Language,
简称为SpEL) , 它能够以一种强大和简洁的方式将值装配到bean属性和构造器参数中, 在这个过程中所使用的表达式会在运行时计算得到值。

SpEL拥有很多特性, 包括:
1.使用bean的ID来引用bean;
2.调用方法和访问对象的属性;
3.对值进行算术、 关系和逻辑运算;
4.正则表达式匹配;
5.集合操作。

首先,SpEL表达式是放到“#{ … }”之中,而属性占位符是放到“${ … }”之中的。下面是几种比较基础的使用方式。

使用方式
如果通过组件扫描(在类上添加@Component)创建bean的话, 在注入属性和构造器参数时, 可以使用@Value注解。这时,使用的不再是占位符,而是SpEL表达式。例如:@Value(“#{systemProperties[‘user.language’]}”)是用来获取用户语言系统的属性。

在XML配置中, 可以将SpEL表达式传入或的value属性中, 或者将其作为p-命名空间、c-命名空间条目的值。

SpEL支持的基础表达式
用SpEL表示字面值,可以用来表示整数、浮点数、 String以及Boolean值。例如#{1}表示整数1、#{1.23}表示小数1.23、#{‘Python’}表示字符串Python、#{true}表示布尔值的true。
此外,还可以用来表示科学记数法。例如:#{1.2E4}表示1.2*10^4即12000。

引用bean、 属性和方法
SpEL能通过ID引用其他的bean。可以使用SpEL将一个bean装配到另外一个bean的属性中, 此时要使用bean ID作为SpEL表达式。例如假设有一个类Test,将其bean ID设置为test,这里使用SpEL表达式表示为#{test}。
再假设Test类有String类型的name属性和一个getName()的方法,那么这里使用SpEL表示引用Test的属性为#{test.name}。而引用Test类的方法的SpEL表达式为#(test.getName()}。

对于被调用方法的返回值来说, 同样可以调用它的方法。例如上述Test类中的getName()方法返回的是一个String,可以调用toUpperCase()将其改为大写,即#(test.getName().toUpperCase()}。但为了避免出现NullPointerException, 可以使用类型安全的运算符:”?.“。这里的完整表达式为#(test.getName()?.toUpperCase()}。
”?.“能够检查它左边的表达式的内容是不是为空,如果为空就不调用它右边的方法,直接返回null。这些检查都是在访问它右边的内容之前完成的。

在表达式中使用类型
如果要在SpEL中访问类作用域的方法和常量的话, 要依赖T()这个关
键的运算符。 例如, 在SpEL中表达Java的Math类, 需要使用T()运算符:T(java.lang.Math)。这里所示的T()运算符的结果会是一个Class对象。
但是T()运算符能够访问目标类型的静态方法和常量。例如, 将PI值装配到bean属性中,即T(java.lang.Math).PI;调用随机数的SpEL表达式为T(java.lang.Math).random()。

SpEL运算符
SpEL提供了许多运算符, 这些运算符可以用在SpEL表达式的值上。详情见下表。
这里写图片描述
例如;#{2*T(java.lang.Math).PI*circle.r}计算了一个bean ID为circle,有个属性为r的圆对象的周长。而计算它的面积为#{T(java.lang.Math).PI*circle.r^2}。“^”是乘方计算的运算符。
比较两个数字是不是相等, 可以使用双等号运算符或文本类型的eq运算符。

当处理文本时, 有时需要检查文本是否匹配某种模式。SpEL通过matches运算符支持表达式中的模式匹配。 matches运算符对String类型的文本(作为左边参数) 应用正则表达式(作为右边参数) 。 matches的运算结果会返回一个Boolean类型的值: 如果与正则表达式相匹配, 则返回true; 否则返回false。正则表达式用’…’括起来。

SpEL中有一些技巧是与集合和数组相关的。 最简单的就是引用列表中的一个元素了:#{company.parkingLots[1].name}这个表达式得到该company下的第2个(从0开始)parkingLot的name属性。
“[]”运算符用来从集合或数组中按照索引获取元素, 实际上, 它还可以从String中获取一个字符。 例如#{‘Python’[1]}表示y。下标也是从0开始。

SpEL还提供了查询运算符(.?[]) , 它会用来对集合进行过滤, 得到集合的一个子集。例如:#{music.songs.?[singer eq ‘Jackson’]}就可以过滤得到所有是Jackson的歌曲。
此外,SpEL还提供了另外两个查询运算符: “.^[]”和“.$[]”, 它们分别用来在集合中查询第一个匹配项和最后一个匹配项。

最后, SpEL还提供了投影运算符(.![]) , 它会从集合的每个成员中选择特定的属性放到另外一个集合中。例如: 假设我们不想要歌曲对象的集合, 而是所有歌曲名称的集合。 如下的表达式会将title属性投影到一个新的String类型的集合中:#{music.songs.![title]}。

SpEL解析过程
SpEL上下文中所定义的每一个表达式都应该首先被解析,然后再被评估。解析的过程采用了ExpressionParser接口的分析器进行处理的。SpelExpressionParser主要负责将字符串表达式解析到已编译的Expression对象中。创建的分析器实例是线程安全的。
在SpEL表达式中,默认情况下,表达式前缀为 ’ # ’ ,而后缀为 ’ } ’ 。如果表达式中没有前缀和后缀,那么表达式字符串就会被当作纯文本。

展开阅读全文

没有更多推荐了,返回首页