Spring学习笔记--Spring表达式语言SpEL

Spring3引入了Spring表达式语言(Spring Expression Language,SpEL)。SpEL是一种强大的、简洁的装配Bean的方式,它通过运行期执行的表达式将值装配到Bean的属性或构造器参数中。
字面值
我们可以在<property>元素的value属性中使用#{}界定符将值装配到Bean的属性中。

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

浮点型数字一样可以出现在SpEL表达式中。

<property name="frequency" value="#{89.7}" />

表达式中的数字也可以实用科学计数法。

<property name="capacity" value="#{1e4}" />

这里将capacity属性设为了10000.0。
String类型的字面值可以使用单引号或者双引号作为字符串界定符。

<property name="name" value="#{‘moonlit‘}" />

或者

<property name="name" value=‘#{"moonlit"}‘ />

还可以使用布尔值true和false。

<property name="enabled" value="#{true}" />

引用Bean
新建Poem类。

package com.moonlit.myspring;

public class Poem {
    private static String[] LINES = {
            "床前明月光,",
            "疑是地上霜。",
            "举头望明月,",
            "低头思故乡。",
    };
    public void perform() {
        for (String line : LINES)
            System.out.println(line);
    }
}

新建Poet类。

package com.moonlit.myspring;

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

public class Poet {
    private Poem poem;
    public void recite() {
        System.out.println("the poet begin to recite...");
        poem.perform();
    }
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "spring-idol.xml");
        Poet poet = (Poet) context.getBean("poet");
        poet.recite();
    }
    public Poem getPoem() {
        return poem;
    }
    public void setPoem(Poem poem) {
        this.poem = poem;
    }
}

并在xml文件中声明他们对应的Bean。

<bean id="poem" class="com.moonlit.myspring.Poem" />
  <bean id="poet" class="com.moonlit.myspring.Poet">
    <property name="poem" value="#{poem}">
  </bean>

poet通过SpEL获得了poem这个Bean。
此时运行Poet程序得到结果如下:

the poet begin to recite...
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。

还可以通过SpEL获得bean的对象。

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

通过这句话就获得了poet的poem。
还可以通过SpEL获得bean的对象。

<property name="poem" value="#{poet.getPoem()}" />

通过这句话通过poet.getPoem()获得poet的poem。
在SpEL中避免抛出空指针异常(NullPointException)的方法是使用null-safe存取器:

<property name="song" value="#{songSelector.selectSong()?.toUpperCase()}" />

这里我们使用 ?. 运算符代替点(.)来访问toUpperCase()方法。在访问邮编方法之前,该运算符会确保左边项的值不为null。所以,如果selectorSong返回null,SpEL就不再尝试调用toUpperCase()方法。
操作类
在SpEL中,使用T()运算符会调用类作用域的方法和常量。例如,在SpEL中使用Java的Math类,我们可以像下面的示例这样使用T()运算符:
T(java.lang.Math)
T()运算符的结果会返回一个java.lang.Math类对象。
装配PI或者一个随机值的配置方法如下:

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

SpEL上还可以执行bean值和数值之间的多种运算。
这里我定义一个Circle类:

package com.moonlit.myspring;

public class Circle {
    private double radius;
    public double getRadius() {
        return radius;
    }
    public void setRadius(double radius) {
        this.radius = radius;
    }
}

它的Bean声明如下:

  <bean id="circle" class="com.moonlit.myspring.Circle">
    <property name="radius" value="2.1" />
  </bean>

使用如下语句进行SpEL的数值运算示例:

<property name="total" value="#{circle.radius + 100.0}" />

“+”还可以进行字符串的连接。
比较值

<property name="hasCapacity" value="#{circle.radius lt 3.3}" />

操作一个表达式的值:
eq(==),lt(<),le(<=),gt(>),ge(>=)。
逻辑表达式:
and,or,not或!。
条件运算符:使用三元运算符

<property name="instrument" value="#{sonSelector.selecSOng()==‘Jingle Bells‘?piano:saxophone}" />

一个常见的三元运算符的使用场景是检查一个值是否为null。

<property name="song" value="#{kenny.song != null ? kenny.song : ‘Greensleeves‘}" />

虽然以上配置可以正常工作,但这里kenny.song的引用重复了两次。SpEL提供了三元运算符的变体来简化表达式:

<property name="song" value="#{kenny.song ?: ‘Greensleeves‘}" />

在以上示例中,如果kenny.song不为null,那么表达式的求值结果是kenny.song,否则就是"Greensleeves"。当我们以这种方式使用时,“?:”通常被称为elvis运算符。这个名字的来历是,使用这个运算符来表示微笑表情(?:) ,头左转90度看)时,问号看起来像猫王(Elvis Presley)的头发。
SpEL支持正则表达式匹配

<property name="validEmail" value="#{admin.email matches ‘[a-zA-Z0-9._%+_][email protected][a-zA-Z0-9.-]+\\.com‘}" />

Hero类用于演示上述的大部分效果:

package com.moonlit.myspring;

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

public class Hero {
    private int count;
    private double frequency;
    private double capacity;
    private String name;
    private boolean enabled;
    private Poem poem;
    private double multiplier;
    private double randomNumber;
    private double total;
    private boolean hasCapacity;
    public void perform() {
        System.out.println("count = " + count);
        System.out.println("frequency = " + frequency);
        System.out.println("capacity = " + capacity);
        System.out.println("name = " + name);
        System.out.println("enabled = " + enabled);
        System.out.println("hero begin to recite...");
        poem.perform();
        System.out.println("pi = " + multiplier);
        System.out.println("random number = " + randomNumber);
        System.out.println("total = " + total);
        System.out.println("hasCapacity = " + hasCapacity);
    }
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "spring-idol.xml");
        Hero hero = (Hero) context.getBean("hero");
        hero.perform();
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public double getFrequency() {
        return frequency;
    }
    public void setFrequency(double frequency) {
        this.frequency = frequency;
    }
    public double getCapacity() {
        return capacity;
    }
    public void setCapacity(double capacity) {
        this.capacity = capacity;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public boolean isEnabled() {
        return enabled;
    }
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    public Poem getPoem() {
        return poem;
    }
    public void setPoem(Poem poem) {
        this.poem = poem;
    }
    public double getMultiplier() {
        return multiplier;
    }
    public void setMultiplier(double multiplier) {
        this.multiplier = multiplier;
    }
    public double getRandomNumber() {
        return randomNumber;
    }
    public void setRandomNumber(double randomNumber) {
        this.randomNumber = randomNumber;
    }
    public double getTotal() {
        return total;
    }
    public void setTotal(double total) {
        this.total = total;
    }
    public boolean isHasCapacity() {
        return hasCapacity;
    }
    public void setHasCapacity(boolean hasCapacity) {
        this.hasCapacity = hasCapacity;
    }

}

Hero.java

spring-idol.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    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-3.0.xsd"
    default-init-method="defaultBorn"
    default-destroy-method="defaultDead" >

  <bean id="poem" class="com.moonlit.myspring.Poem" />
  <bean id="poet" class="com.moonlit.myspring.Poet">
    <property name="poem" value="#{poem}" />
  </bean>
  <bean id="circle" class="com.moonlit.myspring.Circle">
    <property name="radius" value="2.1" />
  </bean>
  <bean id="hero" class="com.moonlit.myspring.Hero">
    <property name="count" value="#{5}" />
    <property name="frequency" value="#{89.7}" />
    <property name="capacity" value="#{1e4}" />
    <!-- <property name="name" value="#{‘moonlit‘}" /> -->
    <property name="name" value=‘#{"moonlit"}‘ />
    <property name="enabled" value="#{true}" />
    <!-- <property name="poem" value="#{poet.poem}" /> -->
    <property name="poem" value="#{poet.getPoem()}" />
    <property name="multiplier" value="#{T(java.lang.Math).PI}" />
    <property name="randomNumber" value="#{T(java.lang.Math).random()}" />
    <property name="total" value="#{circle.radius + 100.0}" />
    <property name="hasCapacity" value="#{circle.radius lt 3.3}" />
  </bean>
</beans>

spring-idol.xml

时间: 2024-09-30 07:46:27

Spring学习笔记--Spring表达式语言SpEL的相关文章

Spring学习笔记--Spring简介

1.spring:给软件行业带来了春天; 2.spring的理念:spring框架的初衷是使的现有的更加实用,spring不是创造轮子(技术或框架),而是使现有的轮子更好的运转;spring本身是一个大杂烩,整合现有的框架技术: 3.Spring优点: 轻量级框架:不具备侵入性(使用某个框架,我们不需要实现它的某个接口,方便框架的替换,原有的代码不需要替换); Ioc容器:控制反转; Aop:面向切面编程; 对事务的支持: 对矿建的支持; ................... 4.主要内容:

Spring学习笔记--Spring IOC

沿着我们上一篇的学习笔记,我们继续通过代码学习IOC这一设计思想. 6.Hello类 第一步:首先创建一个类Hello package cn.sxt.bean; public class Hello { private String name; public void setName(String name) { this.name = name; } public void show(){ System.out.println("hello,"+name); } } 第二步:创建配置

Spring学习笔记——Spring中lazy-init与abstract具体解释

Spring的懒载入的作用是为了避免无谓的性能开销,就是当真正须要数据的时候才去运行数据的载入操作.不只在Spring中.我们在实际的编码过程中也应该借鉴这种思想,来提高我们程序的效率. 首先我们看一段配置文件: <beans> <bean> <bean id="creditService" type="com.jader.service.CreditServiceImpl" lazy-init="true"/>

Spring学习笔记——Spring事务只对运行时异常回滚

我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚,岂不知Spring的事务默认只有在发生运行时异常即:RunTimeException时才会发生事务,如果一个方法抛出Exception或者Checked异常Spring的事务并不会回滚. 下面我们来看看异常的分类,异常一般分为Checked异常和RunTime异常. CheckedException: Java认为Checked异常都是可以被处理的异常,所以Java程序必须显式的处理Checked异常,如果程序没有处理checked

Spring学习笔记——Spring事务仅仅对执行时异常回滚

我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚.岂不知Spring的事务默认仅仅有在发生执行时异常即:RunTimeException时才会发生事务,假设一个方法抛出Exception或者Checked异常Spring的事务并不会回滚. 以下我们来看看异常的分类.异常一般分为Checked异常和RunTime异常. CheckedException: Java觉得Checked异常都是能够被处理的异常,所以Java程序必须显式的处理Checked异常,假设程序没有处理checke

Spring学习笔记——Spring依赖注入原理分析

我们知道Spring的依赖注入有四种方式,分别是get/set方法注入.构造器注入.静态工厂方法注入.实例工厂方法注入 下面我们先分析下这几种注入方式 1.get/set方法注入 public class SpringAction { //注入对象springDao private SpringDao springDao; //一定要写被注入对象的set方法 public void setSpringDao(SpringDao springDao) { this.springDao = spri

Spring学习笔记——Spring中lazy-init与abstract详解

Spring的懒加载的作用是为了避免无谓的性能开销,就是当真正需要数据的时候才去执行数据的加载操作.不仅仅在Spring中,我们在实际的编码过程中也应该借鉴这种思想,来提高我们程序的效率. 首先我们看一段配置文件: <beans> <bean> <bean id="creditService" type="com.jader.service.CreditServiceImpl" lazy-init="true"/&g

Spring学习笔记——Spring中的BeanFactory与FactoryBean

BeanFactory BeanFactory是Spring的org.springframework.beans.factory下的一个接口,是Spring IOC所遵守的基本编程规范,他的实现类有DefaultListableBeanFactory.XmlBeanFactory.ApplicationContext等,都各自实现自己的功能. FactoryBean 通常Spring通过反射机制利用bean的class属性来指定实现类的实例化Bean,在某些情况下实例化Bean的过程比较复杂,如

Spring表达式语言SpEL简介

Spring3引入了Spring表达式语言(Spring Expression Language,SpEL). SpEL有很多特性,比较常用的包括: 1.使用bean的id来引用bean, 下面这个例子就是将卧室这个bean通过SpEL注入到house这个bean的bedroom属性中. <bean id="bedroom" class="go.derek.Bedroom"/> <bean id="house" class=&q