4. 使用表达式装配

使用表达式装配

SpEL导言

我们前面在配置文件中,为Bean注入值是在编译器就已经完成的(可以这么认为),但是如果为属性装配的值要在运行期才能得到,就需要使用表达式来装配。

Spring 3引入Spring表达式语言SpEL,通过在运行期执行的表达式将值装配到Bean的属性或构造器中。

SpEL有许多特性:

  • 使用Bean的ID来引用Bean

  • 调用方法和访问对象的属性

  • 对值进行算术、关系和逻辑运算

  • 正则表达式匹配

  • 集合操作

SpEL的基本原理

SpEL表达式的首要目标就是通过计算获得某个值。

1. 字面值

<property name="count" value="#{100}"/>

#{}标记提示Spring标记里的内容是SpEL表达式。
当然,获取字面值,一般没有必要使用SpEL表达式,这也不能体现出它的优势。

2. 引用Bean、Properties和方法

SpEL能通过ID引用其他Bean

扫描二维码关注公众号,回复: 2756293 查看本文章
<!-- saxophone是一个Bean的id -->
<property name="instrument" value="#{saxophone}"/>

<!--- 等效于 -->
<property name="instrument" ref="saxophone"/>

SpEL可以用Bean的引用来获取Bean的属性

<!-- saxophone是一个Bean的id -->
<property name="instrument" value="#{instrumentalist.song}"/>
<!-- 实际上是调用instrumentalist.getSong() -->

SpEL可调用Bean的方法

<!-- songSelect是一个Bean的id -->
<property name="song" value="#{songSelect.selectSong()}"/>

3. 操作类

在SpEL中,使用T()运算符会访问类作用域的方法和常量

T(java.lang.Math)会返回一个java.lang.Math类对象

T()运算符还可以访问指定类的静态方法和常量

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

4. SpEL提供了几种运算符,可以用在表达式中的值上

Operation Type Operators
算术运算 +,-,*,/,%,^
关系运算
, <, ==, <=, >=, lt, gt, eq, le, ge
逻辑运算 and,or,not,
条件表达式(三目运算符) ? :
正则表达式 matches

5. 在SpEL中筛选集合

  • 访问集合成员

    中括号[]运算符通过索引访问集合中的成员,中括号[]同样可以用来获取java.util.Map集合中的成员。

  • 查询集合成员

    .?[]表示查询出所有匹配项(结果返回的是一个集合)

    <property name=”bigCitys” value=”#{cities.?[population >= 100000]}” />

    .^[]表示查询出第一个匹配项(返回的是一个对象)

    <property name=”bigCitys” value=”#{cities.^[population >= 100000]}” />

    .$[]表示查询出最后一个匹配项(返回的是一个对象)

    <property name=”bigCitys” value=”#{cities.$[population >= 100000]}” />

  • 集合投影·

    从集合的每一个成员中选择特定的属性放入一个新的集合中。投影运算符:.![]

    <property name=”cityNames” value=”#{cities.![name]}” />

示例

City类

package com.li.spring.spel;

public class City {

    private String name;
    private String state;
    private int population;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public int getPopulation() {
        return population;
    }
    public void setPopulation(int population) {
        this.population = population;
    }
    @Override
    public String toString() {
        return "City [name=" + name + ", state=" + state + ", population=" + population + "]";
    }

}

city.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>

<!-- 引用Spring的多个Schema空间的格式定义文件 -->

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

    <!-- 要使用util-list元素,需要先在头部引入util相关的声明 -->                          

    <bean id="city" class="com.li.spring.spel.City"></bean>
    <util:list id="cities">
        <!-- Bean的ID省略掉,因为我们可以通过下标访问到而不需要通过ID来访问它们 -->
        <bean class="com.li.spring.spel.City" p:name="北京" p:state="北京" p:population="10000"></bean>
        <bean class="com.li.spring.spel.City" p:name="上海" p:state="上海" p:population="20000"></bean>
        <bean class="com.li.spring.spel.City" p:name="广州" p:state="广东" p:population="50000"></bean>
        <bean class="com.li.spring.spel.City" p:name="南京" p:state="江苏" p:population="30000"></bean>
        <bean class="com.li.spring.spel.City" p:name="拉萨" p:state="西藏" p:population="10000"></bean>
    </util:list>    

    <bean id="cityTest" class="com.li.spring.spel.CityTest">
        <property name="chosenCity" value="#{cities[1]}"></property>
        <property name="bigCities" value="#{cities.?[population>=30000]}"></property>
        <property name="aBigCity" value="#{cities.^[population>=10000]}"></property>
    </bean>

</beans>

测试类

package com.li.spring.spel;

import java.io.File;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CityTest {

    private City chosenCity;
    private List<City> bigCities;
    private List<City> aBigCity;

    public City getChosenCity() {
        return chosenCity;
    }
    public void setChosenCity(City chosenCity) {
        this.chosenCity = chosenCity;
    }
    public List<City> getBigCities() {
        return bigCities;
    }
    public void setBigCities(List<City> bigCities) {
        this.bigCities = bigCities;
    }
    public List<City> getaBigCity() {
        return aBigCity;
    }
    public void setaBigCity(List<City> aBigCity) {
        this.aBigCity = aBigCity;
    }

    @Override
    public String toString() {
        return "CityTest [chosenCity=" + chosenCity + ", bigCities=" + bigCities + ", aBigCity=" + aBigCity + "]";
    }

    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("com"+File.separator+"li"+File.separator+"spring"+
                                                                   File.separator+"spel"+File.separator+"city.xml");
        CityTest test=(CityTest) ctx.getBean("cityTest");
        System.out.println(test);
    }

}

运行结果:

CityTest [chosenCity=City [name=上海, state=上海, population=20000], bigCities=[City [name=广州, state=广东, population=50000], City [name=南京, state=江苏, population=30000]], aBigCity=[City [name=北京, state=北京, population=10000]]]

猜你喜欢

转载自blog.csdn.net/sinat_37976731/article/details/81362987