Spring表达式语言,简称SpEL(Spring Expression
Language)。SpEL是一种强大的、简洁的装配Bean的方式。SpEL是一个支持运行时查询和操作对象图的强大的动态语言,语法类似于EL表达式,具有诸如显示方法和基本字符串模板函数等特性。
1. 搭建工程
导入jar包:
<dependencies>
<!--Spring基础jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!--junit测试jar包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
完成的工程目录如下:
package pojo;
public class Car {
private String brand;//品牌
private Float price;//价格
private Boolean onSell;//是否销售
//get/setter方法略
}
package pojo;
public class Person {
private String name;
private Car car;
private String socialStatus;
private String phone;
//get/setter方法略
}
package pojo;
import java.util.List;
public class OtherTest {
private Boolean regex;
private Double mathPI;
private Double random;
private String elivis;
private List<Integer> list;
private Integer[] array;
//get/setter方法略
}
2. SpEL语法
SpEL的语法使用#{} SpEL 字面量:
• 整数:#{8}
• 小数:#{8.8}
• 科学计数法:#{1e4}
• String:可以使用单引号或者双引号作为字符串的定界符号。
• Boolean:#{true},#{false} SpEL引用bean
, 属性和方法:
• 引用其他对象:#{car}
• 引用其他对象的属性:#{car.brand}
• 调用其它方法 ,
还可以链式操作:#{car.toString()}
• 调用静态方法静态属性:#{T(java.lang.Math).PI}
SpEL支持的运算符号:
• 算术运算符:+,-,*,/,%,^(加号还可以用作字符串连接)
• 比较运算符:< , > , == , >= , <= , lt , gt , eg , le , ge
• 逻辑运算符:and , or , not , |
• Elivis运算符:
表达式1?:表达式2 。当表达式1为null,返回表达式2
• 三目运算:表达式1?:表达式2:?表达式3。当表达式1为true,返回表达式2,否则返回表达式3
• 正则表达式:#{admin.phone matches ‘\d{8}’} • instanceof:如“’haha’
instanceof T(String)”将返回true。
2.1 注入基本类型
<!--注入基本类型的属性-->
<bean id="car" class="pojo.Car">
<property name="brand" value="#{'BMW'}"/>
<property name="onSell" value="#{true}"/>
<property name="price" value="#{34567.89}"/>
</bean>
注意字符串类型的数据有个单引号’’ 上面的代码等同于以前学的:
<bean id="car" class="pojo.Car">
<property name="brand" value="BMW"/>
<property name="onSell" value="true"/>
<property name="price" value="34567.89"/>
</bean>
测试代码:
public class SpelTest {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
@Test
public void test1() {
Car car=(Car)ac.getBean("car");
System.out.println(car.getBrand());
System.out.println(car.getOnSell());
System.out.println(car.getPrice());
}
}
有输出结果代表成功。
2.2 注入对象类型
<bean id="person" class="pojo.Person">
<!--支持+拼接字符串-->
<property name="name" value="#{'张'+'小明'}"/>
<!--注入另外一个bean 等价于ref="car"-->
<property name="car" value="#{car}"/>
<!--支持简单的逻辑判断如果车超过30000就是小康水平,否则就是温饱-->
<property name="socialStatus" value="#{car.price> 30000 ? '小康':'温饱'}"/>
<property name="phone" value="13712345678"/>
</bean>
测试代码:
@Test
public void test2() {
Person person=(Person)ac.getBean("person");
System.out.println(person.getName());
System.out.println(person.getCar().getBrand());
System.out.println(person.getSocialStatus());
}
2.3 其它方法
<bean id="other" class="pojo.OtherTest">
<!--#{T(类名).静态方法或属性}-->
<property name="mathPI" value="#{T(java.lang.Math).PI}"/>
<property name="random" value="#{T(java.lang.Math).random()}"/>
<!--if判断使用?:-->
<property name="elivis" value="#{car.price>10000?:'豪车'}"/>
<!--正则匹配-->
<property name="regex" value="#{person.phone matches '137\d{8}'}"/>
<!--注入数组-->
<property name="array" value="#{new int[]{1,2,3}}"/>
<!--注入list-->
<property name="list" value="#{{4,5,6}}"/>
</bean>
测试方法:
@Test
public void test3() {
OtherTest test= (OtherTest) ac.getBean("other");
System.out.println(test.getElivis());
System.out.println(test.getMathPI());
System.out.println(test.getRegex());
System.out.println(test.getRandom());
if(test.getArray()!=null){
for (Integer integer : test.getArray()) {
System.out.println(integer);
}
}
if(test.getList()!=null){
for (Integer integer : test.getList()) {
System.out.println(integer);
}
}
}
3. SpEL核心接口
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>版本</version>
</dependency>
SpEL被设计成一个课独立运行的模块,可以脱离Spring容器直接运行。因此只需引入SpEL的模块spring-expression即可,无需引入Spring的其它框架,代码中就可以使用SpEL。
SpEL的核心接口位于prg.springframework.expression包及其子包spel.support中。
在SpEL中,使用表达式只需创建一个SpelExpressionParser(表达式解析器)实例即可。
ExpressionParser parser=new SpelExpressionParser();
Expression exp=parser.parseExpression("'hello'+' spel'");
String value=(String)exp.getValue();
System.out.println(value);
ExpressionParser:用于解析表达式字符串。表达式字符串是用单引号或者转译双引号标注的字符串。
Expression:接口用来计算表达式字符串。
SpEl还支持解析函数,如下:-
Expression exp=parser.parseExpression("'hello '.substring(1)");
EvaluationContext接口提供了属性,方法,字段解析器及类型转化器.默认实现类StandardEvaluationContext的内部使用反射机制来操作对象。
Game game=new Game(1,"abc");
EvaluationContext context = new StandardEvaluationContext(game);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name");
String value = (String) exp.getValue(context);
System.out.println(value);