5、Spring SPEL使用之--在XML中使用SPEL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jaune161/article/details/51476007

SPEL(Spring Expression Language)即Spring3中功能丰富强大的表达式语言,简称SpEL。SpEL是类似于OGNL和JSF EL的表达式语言,能够在运行时构建复杂表达式,存取对象属性、对象方法调用等。所有的SpEL都支持XML和Annotation两种方式,格式:#{ SpEL expression }。

可参考文章
CSDN博主 gudong2945《Spring 表达式语言 (Spring Expression Language) SpEL》
Spring官方文档 第9章 Spring Expression Language (SpEL)

Spring SPEL功能简介

通过spel我们可以实现
1. 通过bean的id对bean进行引用
1. 调用方法以及引用对象中的属性
1. 计算表达式的值
1. 正则表达式的匹配
1. 集合的操作

Spring SPEL配置

Maven依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.2.1.RELEASE</version>
</dependency>

只需要将spring-context添加到依赖即可,spring-context中有对spring-expression的依赖,添加依赖后会自动下载。

Spring配置文件中的配置

增加对P标签和Util的支持,修改schema,添加P和Util

xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"

<!--xsi:schemaLocation中增加-->
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd

最终结果如下

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

</beans>

注入基础类型

<property name="name" value="#{'jaune'}" /> <!--字符串注入,一定要带单引号,如果不带单引号,表示注入的是Bean。也可以用下面的方式-->
<property name="name" value='#{"jaune"}' />

<property name="age" value="#{15}" /> <!--整型-->
<property name="money" value="#{58.6}" /> <!-- 浮点型 -->
<property name="money" value="#{1e4}" /> <!-- 浮点型,科学计数法 -->
<property name="is" value="#{true}" /> <!-- 布尔类型 -->

引用对象、属性和方法

对象引用

语法如下:#{beanId}

<bean id="people" class="com.codestd.springstudy.lesson03.People" />

...
<property name="people" value="#{people}" /> 
<!--等同于使用ref-->
<property name="people" ref="people" /> 

对象属性引用

语法如下:#{beanId.propertyName}

<bean id="people" class="com.codestd.springstudy.lesson03.People">
    <property name="name" value="jaune" />
</bean>

...
<property name="name" value="#{people.name}" />

对象方法引用

语法如下:#{beanId.method()}

<bean id="people" class="com.codestd.springstudy.lesson03.People">
    <property name="name" value="jaune" />
</bean>

...
<property name="name" value="#{people.getName()}" />

还可以链式操作

<property name="name" value="#{people.getName().toUpperCase()}" />

这样写如果people.getName()为null,会抛出空指针异常,为了避免抛出异常我们要使用?.表达式

<property name="name" value="#{people.getName()?.toUpperCase()}" />

调用类的静态方法

语法:T(class.method())

<property name="pi" value="#{T(java.lang.Math).PI}" />

SPEL运算符支持

算术运算符

算数运算符:+, -, *, /, %, ^
语法:#{number+number} #{number-number} ···

<property name="number" value="#{15 + 3}" /> <!-- 18 -->
<property name="number" value="#{15 - 3}" /> <!-- 12 -->
<property name="number" value="#{15 * 3}" /> <!-- 45 -->
<property name="number" value="#{15 / 3}" /> <!-- 5 -->
<property name="number" value="#{15 % 3}" /> <!-- 0 -->
<property name="number" value="#{2 ^ 2}" /> <!-- 4 -->

字符串连接

字符串连接符:+
语法:#{'str1' + 'str2'}

<property name="name" value="#{'wang' + 'chengwei'}" /> <!-- wangchengwei -->
<property name="name" value="#{people.name + 'chengwei'" />

比较运算符

比较运算符: <, >, ==, <=, >=, lt(<), gt(>), eq(==), le(<=), ge(>=)

注意在XML中不能使用>>=需要用gtge代替,<<=亲测可用

<property name="is" value="#{1>2}" /> <!-- false -->
...

逻辑运算符

逻辑运算符号:and, or, not, !

<property name="is" value="#{true and true}" /> <!-- true -->
<property name="is" value="#{true or false}" /> <!-- true -->
<property name="is" value="#{not true}" /> <!-- false -->
<property name="is" value="#{!true}" /> <!-- false -->

if…else表达式

基本语法:条件?true:false

<bean id="people" class="com.codestd.springstudy.lesson03.People">
    <!-- <property name="name" value="jaune" /> -->
</bean>
<property name="name" value="#{people.name != null ? people.name :' wangchengwei'}" />

#wangchengwei

更为简洁的方式

<property name="name" value="#{people.name ?:' wangchengwei'}" />

#wangchengwei

注意:?:之间不能有空格

正则表达式

使用matches关键字,结果为布尔类型

<property name="is" value="#{people.name matches '[a-zA-Z]{2,10}'}" />

SPEL对集合的支持

定义Bean实体类

package com.codestd.springstudy.lesson03;

import org.springframework.stereotype.Component;

public class People {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

List集合

定义集合

    <util:list id="peopleList">
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune001" />
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune002" />
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune003" />
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune004" />
    </util:list>

其中p:name="jaune003"等同于<property name="name" value="jaune003" />

通过下标访问集合中的元素

<property name="people" value="#{peopleList[0]}" />
<property name="name" value="#{peopleList[0].getName()}" />

从Map中获取指定的Key

定义Map集合

<util:map id="peopleMap">
    <entry key="jaune001">
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune001" />
    </entry>
    <entry key="jaune002">
        <bean class="com.codestd.springstudy.lesson03.People" p:name="jaune001" />
    </entry>
</util:map>

通过key访问集合中的元素

<property name="people" value="#{peopleMap['jaune001']}" />
<property name="name" value="#{peopleMap['jaune001'].getName()}" />

从Properties中获取制定的Key

添加Properties文件,文件位置放到spel/setup.properties,文件内容如下

system.name=spel

Properties文件的使用

<util:properties id="setup" location="classpath:spel/setup.properties" />
...
<property name="name" value="#{setup['system.name']}" />

通过下标访问systemEnvironment(系统环境变量)和systemProperties(系统属性)中的值

<property name="name" value="#{systemEnvironment['JAVA_HOME']}" />
<property name="name" value="#{systemProperties['java.version']}" />

在JDK文档中System类中有这样的方法getProperties()在此方法的详细介绍中有下面的参数可供使用:
java.version Java 运行时环境版本
java.vendor Java 运行时环境供应商
java.vendor.url Java 供应商的 URL
java.home Java 安装目录
java.vm.specification.version Java 虚拟机规范版本
java.vm.specification.vendor Java 虚拟机规范供应
java.vm.specification.name Java 虚拟机规范名称
java.vm.version Java 虚拟机实现版本
java.vm.vendor Java 虚拟机实现供应商
java.vm.name Java 虚拟机实现名称
java.specification.version Java 运行时环境规范版本
java.specification.vendor Java 运行时环境规范供应商
java.specification.name Java 运行时环境规范名称
java.class.version Java 类格式版本号
java.class.path Java 类路径
java.library.path 加载库时搜索的路径列表
java.io.tmpdir 默认的临时文件路径
java.compiler 要使用的 JIT 编译器的名称
java.ext.dirs 一个或多个扩展目录的路径
os.name 操作系统的名称
os.arch 操作系统的架构
os.version 操作系统的版本
file.separator 文件分隔符(在 UNIX 系统中是“/”)
path.separator 路径分隔符(在 UNIX 系统中是“:”)
line.separator 行分隔符(在 UNIX 系统中是“/n”)
user.name 用户的账户名称
user.home 用户的主目录
user.dir 用户的当前工作目录

获取字符串中的某个字符

可直接通过下标获取字符串中的某个字符

<property name="name" value="#{systemProperties['java.version'][0]}" />

条件筛选

筛选子集

<property name="people" value="#{peopleList.?[name == 'jaune004'][0]}" />

<!--表示取第一个-->
<property name="people" value="#{peopleList.^[name == 'jaune004']}" />
<!--表示取最后一个-->
<property name="people" value="#{peopleList.$[name == 'jaune004']}" />

peopleList.?[name == 'jaune004']筛选出的是一个List集合,后面加上下标表示取第1个。

注意:这种写法在无法匹配到元素时会报错

集合的投影

语法:.![],集合返回的是集合,在Bean中先添加集合属性

private List<String> names;
<property name="names" value="#{peopleList.![name]}"></property>

返回:names[jaune001, jaune002, jaune003, jaune004]

转载于:https://my.oschina.net/jaune161/blog/3015846

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值