一、什么是Spring表达式
Spring表达式,又称为SpEL(Sprig Expression Language),是Spring Framework中专门用来进行计算和属性取值的表达式语言。SpEL的功能十分强大,支持调用方法、进行正则表达式匹配等复杂操作,并且可以与Spring IoC容器、Spring AOP等其他功能一起使用。
二、SpEL的语法
SpEL的语法比较简单,常用的操作符有加减乘除、逻辑运算符、比较运算符等。SpEL的语法主要由三个部分组成,分别是:属性、方法和表达式。
- 属性:SpEL可以直接访问JavaBean的属性,示例代码如下:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 获取Person实例中的属性值
Person person = new Person();
person.setName("Tom");
person.setAge(18);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name");
String name = (String) exp.getValue(person); // name值为Tom
- 方法:SpEL中可以调用JavaBean中的方法,示例代码如下:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
// 调用Calculator中的add方法
Calculator calculator = new Calculator();
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("add(1,2)");
int result = (Integer) exp.getValue(calculator); // result值为3
- 表达式:SpEL中可以使用各种运算符进行复杂的运算,示例代码如下:
ExpressionParser parser = new SpelExpressionParser();
// 计算 1+2+3+4+5
Expression exp = parser.parseExpression("1+2+3+4+5");
int result1 = (Integer) exp.getValue(); // result1值为15
// 将字符串转换为大写形式
Expression exp2 = parser.parseExpression("'hello'.toUpperCase()");
String result2 = (String) exp2.getValue(); // result2值为"HELLO"
// 判断整数num的值是否大于0
int num = -1;
Expression exp3 = parser.parseExpression("num > 0");
boolean result3 = (Boolean) exp3.getValue(); // result3值为false
三、变量和上下文
SpEL提供了两种类型的变量,分别是根对象和上下文变量。根对象可以通过设置EvaluationContext中的rootObject属性来设置;上下文变量可以通过setVariable方法来设置。示例代码如下:
// 计算person对象中name属性的长度
Person person = new Person();
person.setName("Tom");
EvaluationContext context = new StandardEvaluationContext(person);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name.length()");
int result1 = (Integer) exp.getValue(context); // result1值为3
// 计算num是否在min和max之间
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("min", 1);
context.setVariable("max", 10);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("num > min and num < max");
boolean result2 = (Boolean) exp.getValue(context); // result2值为false
四、SpEL与Spring IoC容器的整合
SpEL可以与Spring IoC容器无缝整合,可以使用SpEL表达式来进行Bean的注入等操作。示例代码如下:
<!-- 在XML配置文件中使用SpEL进行属性值注入 -->
<bean id="person" class="com.example.Person">
<property name="name" value="#{systemProperties['user.name']}" />
<property name="age" value="#{ T(Integer).parseInt('${person.age}') }" />
</bean>
// 在JavaConfig中使用SpEL进行属性值注入
@Configuration
public class AppConfig {
@Value("#{ systemProperties['os.name'] }")
private String osName;
@Bean
public Person person() {
Person person = new Person();
person.setName("Tom");
person.setAge(#{ T(Integer).parseInt('${person.age}') });
return person;
}
}
五、SpEL的高级应用
除了上述常见的用法外,SpEL还可以进行正则表达式匹配、集合过滤、集合投影等高级操作。示例代码如下:
// 进行正则表达式匹配
String email = "example@test.com";
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'example@test.com'.matches('[a-z]+@[a-z]+\\.[a-z]+')");
boolean result1 = (Boolean) exp.getValue(); // result1值为true
// 对集合进行过滤和投影
List<Person> personList = new ArrayList<>();
Person p1 = new Person();
p1.setName("Tom");
p1.setAge(18);
Person p2 = new Person();
p2.setName("Jerry");
p2.setAge(20);
Person p3 = new Person();
p3.setName("Alice");
p3.setAge(22);
personList.add(p1);
personList.add(p2);
personList.add(p3);
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("personList", personList);
ExpressionParser parser = new SpelExpressionParser();
Expression exp1 = parser.parseExpression("#personList.?[age > 19]"); // 过滤年龄大于19岁的Person
List<Person> result2 = (List<Person>) exp1.getValue(context); // result2值为[p2, p3]
Expression exp2 = parser.parseExpression("#personList.![name]"); // 投影出三个Person的name属性,返回一个List
List<String> result3 = (List<String>) exp2.getValue(context); // result3值为["Tom", "Jerry", "Alice"]