SpEL(Spring Expression Language)是 Spring 框架提供的强大表达式语言,用于在运行时查询和操作对象图。SpEL 支持多种表达式类型,包括字面量、方法调用、属性访问、算术运算、逻辑运算、变量引用等。下面是一些常见的使用场景和案例。
1. 字面量和简单表达式
场景:简单的字符串拼接
String result = parser.parseExpression("'Hello, ' + 'World!'").getValue(String.class);
// result = "Hello, World!"
场景:数值运算
int result = parser.parseExpression("2 + 3 * 2").getValue(Integer.class);
// result = 8
2. 属性访问
场景:访问对象的属性
public class Person {
private String name;
private int age;
// Getters and Setters
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 = new Person();
person.setName("John Doe");
person.setAge(30);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(person);
String name = parser.parseExpression("name").getValue(context, String.class);
int age = parser.parseExpression("age").getValue(context, Integer.class);
// name = "John Doe"
// age = 30
3. 方法调用
场景:调用对象的方法
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
Calculator calculator = new Calculator();
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(calculator);
int result = parser.parseExpression("add(10, 20)").getValue(context, Integer.class);
// result = 30
4. 集合操作
场景:访问集合中的元素
List<String> list = Arrays.asList("apple", "banana", "cherry");
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("list", list);
String firstItem = parser.parseExpression("#list[0]").getValue(context, String.class);
// firstItem = "apple"
boolean containsBanana = parser.parseExpression("#list.contains('banana')").getValue(context, Boolean.class);
// containsBanana = true
5. 条件表达式
场景:条件判断
Person person = new Person();
person.setName("John Doe");
person.setAge(30);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(person);
boolean isAdult = parser.parseExpression("age >= 18").getValue(context, Boolean.class);
// isAdult = true
String greeting = parser.parseExpression("age >= 18 ? 'Hello, adult' : 'Hello, child'").getValue(context, String.class);
// greeting = "Hello, adult"
6. 变量引用
场景:引用上下文中的变量
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("name", "Alice");
context.setVariable("age", 25);
String greeting = parser.parseExpression("name + ' is ' + age + ' years old'").getValue(context, String.class);
// greeting = "Alice is 25 years old"
7. 类型转换
场景:类型转换
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
String numberStr = "123";
int number = parser.parseExpression("T(Integer).parseInt(#numberStr)").getValue(context, Integer.class);
// number = 123
8. 注解中的 SpEL 表达式
场景:在注解中使用 SpEL 表达式
假设你有一个方法需要根据传入的用户对象生成锁的键:
public class SysUser {
private String username;
// Getter and Setter
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
public class MyService {
@DistributedLock(key = "#user.username", keyPrefix = "lock:")
public void someMethod(SysUser user) {
// 方法逻辑
}
}
9. 安全性和性能
场景:确保 SpEL 表达式的安全性
在使用 SpEL 表达式时,需要注意安全性和性能问题。特别是当表达式来自用户输入时,应进行严格的验证和限制,以防止潜在的安全漏洞。
总结
SpEL 是一个非常强大的工具,适用于多种场景,包括属性访问、方法调用、集合操作、条件表达式、变量引用等。通过合理使用 SpEL,可以简化代码逻辑,提高开发效率。