Spring之SpEL

前言

Spring3引入了Spring表达式语言(SpEL),可以像jsp中的el表达式一样,在运行期动态执行,从而得到需要的值。
SpEL的特性包括:
- 使用Bean的ID来引用Bean
- 调用方法和访问对象的属性
- 对值进行算术、关系和逻辑运算
- 正则表达式匹配
- 集合操作

字面值

字面值是最简单的SpEL表达式。一个简单的SpEL表达式如下:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="age" value="#{5}" />
</bean>

#{}符号标记该内容为SpEL表达式。
浮点型数字也可以出现在SpEL表达式中:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="age" value="#{5.2}" />
</bean>

还可以使用科学计数法:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="age" value="#{1e4}" />
</bean>
age = 10000.0;

还可以true或者false:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="married" value="#{false}"/>
</bean>

String类型的字面值可以使用单引号或者双引号作为字符串的界定符:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{'Stream'}" />
</bean>

引用Bean、Properties和方法

SpEL的另外一个基本应用是使用ID来引用其它Bean。

<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="name" value="Stream"/>
</bean>
<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{manager.name}" />
</bean>

还可以调用Bean中的方法:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{manager.getManagerName()}" />
</bean>

将名字变为小写:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
   <property name="managerName" value="#{manager.getManagerName().toLowerCase()}" />
</bean>

上面的调用方式中,如果getManagerName()返回null,那么将会报错:

org.springframework.expression.spel.SpelEvaluationException: EL1011E:(pos 25): Method call: Attempted to call method toLowerCase() on null context object

为了避免null值的出现导致错误,可以用(?.)代替(.),这样当出现null时将忽略后面的操作。
对于字符串,可以使用[]根据索引取到相应的结果:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{T(com.stream.spring.util.StringUtil).toString('Streamwei')[3]}" />
</bean>
employee.managerName = "e";

注意索引是从0开始。

操作类

SpEL还能调用类的静态方法和和常量,使用T()运算符即可。

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{T(com.stream.spring.util.ConstUtil).MANAGER}" />
</bean>

如上面的代码,在com.stream.spring.util.ConstUtil中定义了一个常量,T(com.stream.spring.util.ConstUtil)返回ConstUtil的一个实例,然后取到该实例的MANAGER字段。静态方法一样的道理:

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="managerName" value="#{T(com.stream.spring.util.StringUtil).toString('Streamwei')}" />
</bean>

算术运算和逻辑运算

SpEL提供了多种运算符来操作表达式。

运算符类型运算符
算术运算符+、-、*、/、%、^(乘方运算)
关系运算符<(lt)、>(gt)、==(eq)、<=(le)、>=(ge)
逻辑符类型and、or、not、!
条件运算?A:B
正则表达式matches

算术运算符中,除了+之外,其余的要求参与运算的都是数字。+的两边可以是字符串,这时候执行字符串合并的操作。操作数既可以是字面量,也可以是用SpEL求到的值。

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
     <property name="age" value="#{30}"/>
     <!--<property name="managerName" value="#{employee2.age >= 27 ? true : false}" />-->
     <property name="married" value="#{employee2.age ge 27 ? true : false}" />
 </bean>

matches运算符有两个操作数,左边的参数是要检测的字符串,右边的参数是正则表达式,如果字符串匹配正则表达式返回true,否则返回false。

<bean id="employee" class="com.stream.spring.spel.entity.Employee">
    <property name="age" value="#{30}"/>
    <property name="married" value="#{employee2.age matches '[0-9.]+'}" />
</bean>
employee.married = true

操作集合

SpEL主要用三个运算符来操作集合:

运算符返回值
.?[]根据条件在给定集合中查询元素,并返回一个由查询出的元素组成的新集合
.^[]、.$[]从给定集合中查询第一个、最后一个元素,返回集合中的元素
.![]从集合的每一个成员中选择指定的属性,返回一个新的集合,新的集合类型和原有集合不一定相同

首先定义一个list:

<util:list id="employees">
    <bean id="employee1" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee1"/>
        <property name="age" value="21"/>
    </bean>
    <bean id="employee2" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee2"/>
        <property name="age" value="22"/>
    </bean>
    <bean id="employee3" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee3"/>
        <property name="age" value="23"/>
    </bean>
    <bean id="employee4" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee4"/>
        <property name="age" value="24"/>
    </bean>
    <bean id="employee5" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee5"/>
        <property name="age" value="25"/>
    </bean>
    <bean id="employee6" class="com.stream.spring.spel.entity.Employee">
        <property name="name" value="employee6"/>
        <property name="age" value="26"/>
    </bean>
</util:list>
  1. 用[]来获取集合
<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employees" value="#{employees[3]}"/>
</bean>
Result:
manager.employees.size() = 1;
manager.employees.get(0).getName = "employee4";
  1. 使用.?[]筛选出age>=23的记录
<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employees" value="#{employees.?[age ge 23]}"/>
</bean>
Result:
manager.employees.size() = 4;
manager.employees.get(0).getName = "employee3";
  1. 使用.^[]筛选出age>=23的记录的第一个元素
<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employee" value="#{employees.^[age ge 23]}"/>
</bean>
Result:
mananer.employee.name = "employee3";
  1. 使用.$[]筛选出age>=23的记录的最后一个元素
<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employee" value="#{employees.$[age ge 23]}"/>
</bean>
Result:
mananer.employee.name = "employee6";
  1. 使用.![]讲age>=23的元素的name抽取出来形成一个List
<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employeesName" value="#{employees.?[age ge 23].![name]}"/>
</bean>
Result:
manager.employeesName.size = 4;
manager.employeesName.get(0) = "employee3";
manager.employeesName.get(1) = "employee4";
manager.employeesName.get(2) = "employee5";
manager.employeesName.get(3) = "employee6";

注意.![]的筛选条件,不能写成[‘name’],否则会把’name’作为一个字符串:

<bean id="manager" class="com.stream.spring.spel.entity.Manager">
    <property name="employeesName" value="#{employees.?[age ge 23].![name]}"/>
</bean>
Result:
manager.employeesName.size = 4;
manager.employeesName.get(0) = "name";
manager.employeesName.get(1) = "name";
manager.employeesName.get(2) = "name";
manager.employeesName.get(3) = "name";
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值