什么是SpEL
- Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
- 语法类似于 EL表达式:SpEL 使用 #{…}作为定界符,所有在大框号中的字符都将被认为是 SpEL。
- SpEL 为 bean 的属性进行动态赋值提供了便利 通过 SpEL 可以实现:
- 通过 bean 的 id 对 bean 进行引用
- 调用方法以及引用对象中的属性
- 计算表达式的值
- 正则表达式的匹配
SpEL很重要的一个功能就是能够实现 动态赋值
字面量表达式
字面量的表示:
整数:<property name="count" value="#{5}"/>
小数:<property name="frequency" value="#{89.7}"/>
科学计数法:<property name="capacity" value="#{1e4}"/>
String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/>
Boolean:<property name="enabled" value="#{false}"/>
以上的用法其实没有什么意义,并不能体现出SpEL的强大,这里些出来只是简单介绍下用法而已。
SpEL使用
举个例子:
先创建三个类
- Address类:
package com.spring.spel;
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [province=" + province + ", city=" + city + "]";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- Car类:
package com.spring.spel;
public class Car {
private String brand;
private double price;
//轮胎的周长
private double tyrePerimeter;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getTyrePerimeter() {
return tyrePerimeter;
}
public void setTyrePerimeter(double tyrePerimeter) {
this.tyrePerimeter = tyrePerimeter;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", price=" + price + ", tyrePerimeter="
+ tyrePerimeter + "]";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- Person类:
package com.spring.spel;
public class Person {
private String name;
private Car car;
private String city;
private String info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Person [name=" + name + ", car=" + car + ", city=" + city
+ ", info=" + info + "]";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- bean配置文件:
<!-- 使用spel赋字面值 -->
<bean id="address" class="com.spring.spel.Address">
<property name="province" value="#{'安徽'}"></property>
<property name="city" value="#{'合肥'}"></property>
</bean>
<!-- 使用spel引用类的静态属性 -->
<bean id="car" class="com.spring.spel.Car">
<property name="brand" value="bmw"></property>
<property name="price" value="350000"></property>
<!-- 引用Math类的静态属性PI -->
<property name="tyrePerimeter" value="#{T(java.lang.Math).PI * 80}"></property>
</bean>
<bean id="person" class="com.spring.spel.Person">
<property name="name" value="tom"></property>
<!-- 使用spel引用其他的bean -->
<property name="car" value="#{car}"></property>
<!-- 使用spel引用其他bean的属性 -->
<property name="city" value="#{address.city}"></property>
<!-- 使用spel语法判断 -->
<property name="info" value="#{car.price > 300000 ? '金领' : '白领'}"></property>
</bean>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 测试类:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-spel.xml");
Address address = (Address) ctx.getBean("address");
System.out.println(address);
Car car = (Car) ctx.getBean("car");
System.out.println(car);
Person person = (Person) ctx.getBean("person");
System.out.println(person);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
总结:
#{T(java.lang.Math).PI
:使用java类的静态属性#{car}
: 使用spel引用其他的bean#{address.city}
:使用spel引用其他bean的属性#{car.price > 300000 ? '金领' : '白领'}
:使用spel条件判断
SpEL其他用法:
- 调用其他bean实例的方法,还可以连缀操作
<property name="city" value="#{address.getCity().getXxx}"></property>
- 1
- 算数运算符:+, -, *, /, %, ^:
- 加号还可以用作字符串连接:
- 比较运算符: eq(==),lt(<),le(<=),gt(>),ge(>=) 括号里面外面的都可以使用
- 逻辑表达式:and,or,not或!。
- SpEL支持正则表达式匹配
<property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+_]+@[a-zA-Z0-9.-]+\\.com'}" />
- 1
注解使用SpEl
利用@Value注解可以给实体属性赋默认值
@Value可以使用SpEL表达式,例如:
@Value("#{'福建'}")
private String province;
@Value("#{'福州'}")
private String city;
- 1
- 2
- 3
- 4
- 5
使用前需要开启注解扫描器:
<context:component-scan base-package="com.spring"></context:component-scan>