当前位置: 首页> 汽车> 新车 > 西瓜创客少儿编程加盟_丹东企业网站建设平台_论坛发帖_中国互联网协会

西瓜创客少儿编程加盟_丹东企业网站建设平台_论坛发帖_中国互联网协会

时间:2025/7/13 6:49:42来源:https://blog.csdn.net/kersixy/article/details/143480216 浏览次数: 3次
西瓜创客少儿编程加盟_丹东企业网站建设平台_论坛发帖_中国互联网协会

1. 什么是 SpEL?

SpEL(Spring Expression Language)是 Spring 框架提供的一个强大的表达式语言,用于在运行时查询和操作对象图。它类似于 JSP EL(JavaServer Pages Expression Language)和 OGNL(Object-Graph Navigation Language),但在功能上更为丰富和强大。

官网文档:6. Spring Expression Language (SpEL)

中文文档:8. Spring 表达式语言 (SpEL)

2. SpEL 的主要特点

  1. 灵活性:可以在配置文件和代码中使用。
  2. 丰富的语法:支持字面量、变量引用、属性访问、方法调用、算术运算、逻辑运算、三元运算、集合操作、正则表达式等。
  3. 类型转换:自动进行类型转换。
  4. 对象图导航:可以方便地导航复杂的对象图。
  5. 环境变量访问:可以访问系统属性和环境变量。

3. SpEL 的基本语法

类别

描述

语法示例

备注

字面量

常量值,如字符串、数字、布尔值、空值等

'Hello, World!'

字符串需要用单引号或双引号包围

123

数字可以直接写

true

布尔值直接写

null

空值直接写

变量引用

引用环境中的变量

#{systemProperties['os.name']}

使用 #{...} 语法引用变量

属性访问

访问对象的属性

#{customer.name}

使用点号 . 访问对象属性

方法调用

调用对象的方法

#{customer.getName()}

使用点号 . 调用对象方法

算术运算

基本的算术运算

#{1 + 2}

支持 +, -, *, /, %, ^ 运算符

逻辑运算

逻辑运算符

#{1 == 2}

支持 ==, !=, <, >, <=, >=, and, or, not 运算符

三元运算

三元运算符

#{1 > 2 ? 'yes' : 'no'}

格式为 condition ? true-expression : false-expression

集合操作

操作集合和数组

#{T(java.util.Arrays).asList('a', 'b', 'c').contains('b')}

使用 T(...) 引用静态方法

正则表达式

正则表达式匹配

#{'Hello'.matches('H.*')}

使用 matches 方法进行匹配

类型转换

自动类型转换

#{'30'}

自动将字符串转换为数字

对象图导航

导航对象图

#{customer.address.city}

使用点号 . 导航对象图

环境变量

访问系统环境变量和属性

#{systemProperties['user.name']}

访问系统属性

#{systemEnvironment['AGE']}

访问环境变量

 4. 常用Spring的表达接口

4.1 class SpelExpressionParser

所属包:org.springframework.expression.spel.standard

父接口:org.springframework.expression.ExpressionParser

构造方法:

方法名

描述

SpelExpressionParser()

创建一个新的 SpelExpressionParser 实例。

示例代码:

SpelExpressionParser parser = new SpelExpressionParser();

方法:

方法名

返回值类型

描述

parseExpression(String expressionString)

Expression

解析给定的表达式字符串并返回 Expression 对象。

示例代码: 

ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("'Hello, World!'");

4.2 interface Expression

所属包:org.springframework.expression

方法:

方法名

返回值类型

描述

getValue()

Object

计算表达式的值并返回结果。

getValue(EvaluationContext context)

Object

在给定的上下文中计算表达式的值并返回结果。

getValue(EvaluationContext context, Class<T> desiredResultType)

T

在给定的上下文中计算表达式的值,并将其转换为指定的类型。

示例代码:

ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("'Hello, World!'");
StandardEvaluationContext context = new StandardEvaluationContext();
// getValue()
Object value1 = expression.getValue();
// getValue(EvaluationContext context)
Object value2 = expression.getValue(context);
// getValue(EvaluationContext context, Class<T> desiredResultType)
Object value3 = expression.getValue(context, String.class);

4.2 class StandardEvaluationContext

所属包:org.springframework.expression.spel.support

父接口:org.springframework.expression.EvaluationContext

构造方法:

方法名

描述

StandardEvaluationContext()

创建一个新的 StandardEvaluationContext 实例。

StandardEvaluationContext(Object rootObject)

使用给定的根对象创建一个新的 StandardEvaluationContext 实例。

示例代码:

StandardEvaluationContext context1 = new StandardEvaluationContext();
MyBean myBean = new MyBean();
StandardEvaluationContext context2 = new StandardEvaluationContext(myBean);public class MyBean {private int number = 10;public int getNumber() {return number;}
}

方法:

方法名

返回值类型

描述

setVariable(String name, Object value)

void

在上下文中设置一个变量及其值。

示例代码:

StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("number", 10);

4.3 SpEL 的基本语法示例代码

public class Address {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}
}
public class Customer {private String name;private int age;private Address address;private Customer() {}public Customer(String name, int age) {this.name = name;this.age = 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;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}
}
public static void main(String[] args) {// 1.字面量ExpressionParser parser = new SpelExpressionParser();String result = parser.parseExpression("'Hello, World!'").getValue(String.class);System.out.println(result); // 输出: Hello, World!// 2.变量引用StandardEvaluationContext context = new StandardEvaluationContext();context.setVariable("osName", System.getProperty("os.name"));String osName = parser.parseExpression("'OS Name: ' + #osName").getValue(context, String.class);System.out.println(osName); // 输出: OS Name: Windows 11// 3.属性访问Customer customer = new Customer("John Doe", 30);context.setRootObject(customer);String name = parser.parseExpression("name").getValue(context, String.class);System.out.println(name); // 输出: John Doe// 4.方法调用String upperCaseName = parser.parseExpression("name.toUpperCase()").getValue(context, String.class);System.out.println(upperCaseName); // 输出: JOHN DOE// 5.算术运算int agePlusTen = parser.parseExpression("age + 10").getValue(context, Integer.class);System.out.println(agePlusTen); // 输出: 40// 6.逻辑运算boolean isAdult = parser.parseExpression("age >= 18").getValue(context, Boolean.class);System.out.println(isAdult); // 输出: true// 7.三元运算String ageGroup = parser.parseExpression("age >= 18 ? 'Adult' : 'Minor'").getValue(context, String.class);System.out.println(ageGroup); // 输出: Adult// 8.集合操作Map<String, Map<String, String>> nestedMap = parser.parseExpression("{'person':{'name':'John','age':'30'}}").getValue(context, Map.class);System.out.println(nestedMap); // 输出: {person={name=John, age=30}}// 9.正则表达式匹配boolean matches = parser.parseExpression("'Hello'.matches('H.*')").getValue(Boolean.class);System.out.println(matches); // 输出: true// 10.类型转换int age = parser.parseExpression("'30'").getValue(Integer.class);System.out.println(age); // 输出: 30// 11.对象图导航Address address = new Address("New York");customer.setAddress(address);context.setRootObject(customer);String city = parser.parseExpression("address.city").getValue(context, String.class);System.out.println(city); // 输出: New York// 12.环境变量访问context.setVariable("systemProperties", System.getProperties());String javaHome = parser.parseExpression("#systemProperties['java.home']").getValue(context, String.class);System.out.println(javaHome);
}

5. SpEL 常见使用位置和场景

测试案例:GitHub - kerrsixy/spel-demo: SpEL表达式测试代码

1. 配置文件中

在 Spring 的 XML 配置文件中,你可以使用 SpEL 来动态设置 bean 属性。

<bean id="person" class="com.example.Person"><property name="name" value="#{'John Doe'}"/><property name="age" value="#{25 + 5}"/>
</bean>

2. 注解中

在 Spring 的注解中,你也可以使用 SpEL 来动态设置属性值。

@Data
@Component
public class Person {@Value("#{'John Doe'}")private String name;@Value("#{25 + 5}")private int age;
}

3. 方法参数中

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {@GetMapping("/greet")public String greet(@Value("#{'Hello, ' + T(java.lang.System).currentTimeMillis()}") String message) {return message;}
}

4. AOP 切面中

在 Spring AOP 切面中,你可以使用 SpEL 来动态决定切点和通知的执行。

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Slf4j
@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.zjp.speldemo.service.*.*(..)) && args(name) && @annotation(com.zjp.speldemo.annotation.Loggable)")public void logMethodEntry(@Value("#{name}") String name) {log.info("Entering method with name: {}", name);}
}

5. 与其他Spring组件

SpEL还可以在其他Spring组件中使用,比如在@Cacheable注解中定义缓存键:

import com.zjp.speldemo.entity.User;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {@GetMapping@Cacheable(cacheNames = "userCache", key = "#id")public User getById(String id) {User user = new User(id, "zhangsan", 18);return user;}
}
关键字:西瓜创客少儿编程加盟_丹东企业网站建设平台_论坛发帖_中国互联网协会

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: