Spring Expression Language 简明教程
Spring SpEL - Overview
Spring 表达式语言(SpEL)是一种非常强大的表达式语言,它支持在运行时查询和操作对象图。它提供了许多高级特性,例如方法调用和基本字符串模板化功能。
Spring 表达式语言最初是为 Spring 社区创建的,以用于 Spring 产品组合中的所有产品中单一且受良好支持的表达式语言。虽然 SpEL 作为 Spring 产品组合中表达式评估的基础,它并不直接关联 Spring,并且可以独立使用。
以下是 Spring 表达式语言(SpEL)支持的功能列表:
-
Literal expressions
-
Boolean and relational operators
-
Regular expressions
-
Class expressions
-
访问属性、数组、列表、映射
-
Method invocation
-
Relational operators
-
Assignment
-
Calling constructors
-
Bean references
-
Array construction
-
Inline lists
-
Ternary operator
-
Variables
-
User defined functions
-
Collection projection
-
Collection selection
-
Templated expressions
我们将在下一章中涵盖每一个主题。
Spring SpEL - Environment Setup
本章将在您开始使用 Spring 框架时,指导您如何准备开发环境。它还将教您在设置 Spring 框架之前如何在您的机器上设置 JDK、Maven 和 Eclipse −
Setup Java Development Kit (JDK)
你可以从 Oracle 的 Java 站点下载 SDK 的最新版本 − Java SE Downloads. 你在下载文件中可以找到安装 JDK 的说明,按照给定的说明进行安装和配置。最后设置 PATH 和 JAVA_HOME 环境变量以引用包含 java 和 javac 的目录,通常分别为 java_install_dir/bin 和 java_install_dir。
如果您运行的是 Windows 且在 C:\jdk-11.0.11 中安装了 JDK,那么您将不得不把以下代码行放入您的 C:\autoexec.bat 文件中。
set PATH=C:\jdk-11.0.11;%PATH%
set JAVA_HOME=C:\jdk-11.0.11
或者,在 Windows NT/2000/XP 中,你必须右键单击我的电脑,选择属性 → 高级 → 环境变量。然后,你将不得不更新 PATH 值并单击确定按钮。
在 Unix(Solaris、Linux 等)中,如果 SDK 安装在 /usr/local/jdk-11.0.11 且您使用 C shell,那么您将不得不把以下代码行放入您的 .cshrc 文件中。
setenv PATH /usr/local/jdk-11.0.11/bin:$PATH
setenv JAVA_HOME /usr/local/jdk-11.0.11
或者,如果你使用诸如 Borland JBuilder、Eclipse、IntelliJ IDEA 或 Sun ONE Studio 这样的集成开发环境 (IDE),则必须编译并运行一个简单程序来确认 IDE 知道你在何处安装了 Java。否则,你必须按照 IDE 文档中给出的内容执行正确的设置。
Setup Eclipse IDE
本教程中的所有示例都是使用 Eclipse IDE 编写的。因此,我们建议你应该在你机器上安装 Eclipse 的最新版本。
要安装 Eclipse IDE,请从 www.eclipse.org/downloads 下载最新的 Eclipse 二进制文件。下载安装文件后,将二进制分发包解压到方便的位置。例如,在 Windows 上的 C:\eclipse 中,或 Linux/Unix 上的 /usr/local/eclipse 中,最后相应地设置 PATH 变量。
可以通过在 Windows 机器上执行以下命令启动 Eclipse,或者你只需双击 eclipse.exe
%C:\eclipse\eclipse.exe
可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令启动 Eclipse −
$/usr/local/eclipse/eclipse
成功启动后,如果一切正常,它应该显示以下结果 −
Set Maven
在本教程中,我们使用 maven 来运行和构建基于 Spring 的示例。请按照 Maven - Environment Setup 安装 maven。
我们将在下一章中涵盖每一个主题。
Spring SpEL - Create Project
使用 Eclipse,选择 File → New * → *Maven Project 。勾选 Create a simple project(skip archetype selection) ,然后单击下一步。
按照以下所示输入详细信息 −
-
groupId − com.tutorialspoint
-
artifactId − springspel
-
version − 0.0.1-SNAPSHOT
-
name − springspel
-
description − Spring SpEL 项目
单击完成按钮,将创建一个新项目。
pom.xml
使用 Spring Core 依赖项更新 pom.xml。以下是 pom.xml 的完整内容
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>springspel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springspel</name>
<description>Spring SpEL Project</description>
<properties>
<org.springframework.version>5.3.9</org.springframework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
applicationcontext.xml
在 *src → main → resources * 中创建 applicationcontext.xml,其内容如下。
applicationcontext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>
Spring SpEL - Expression Interface
ExpressionParser 是 Spring SpEL 的主接口,用于将表达式字符串解析成已编译表达式。这些已编译表达式可以评估并支持解析模板以及标准表达式字符串。
Syntax
以下是创建 ExpressionParser 并使用其对象来获取值的一个示例。
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Welcome to Tutorialspoint'");
String message = (String) exp.getValue();
它应按如下方式打印结果−
Welcome to Tutorialspoint
-
ExpressionParser − 一个负责解析表达式字符串的接口。
-
Expression − 一个负责评估表达式字符串的接口。
-
Exceptions − 在解析表达式和方法调用时可引发 ParseException 和 EvaluationException。
SpEL 支持调用方法、调用构造函数和访问属性。以下示例显示各种用例。
Example
以下示例显示一个类 MainApp。
让我们更新在 Spring SpEL - Create Project 章节中创建的项目。我们正在添加以下文件−
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class MainApp {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
// parse a plain text
Expression exp = parser.parseExpression("'Welcome to tutorialspoint'");
String message = (String) exp.getValue();
System.out.println(message);
// invoke a method
exp = parser.parseExpression("'Welcome to tutorialspoint'.concat('!')");
message = (String) exp.getValue();
System.out.println(message);
// get a property
exp = parser.parseExpression("'Welcome to tutorialspoint'.bytes");
byte[] bytes = (byte[]) exp.getValue();
System.out.println(bytes.length);
// get nested properties
exp = parser.parseExpression("'Welcome to tutorialspoint'.bytes.length");
int length = (Integer) exp.getValue();
System.out.println(length);
//Calling constructor
exp = parser.parseExpression("new String('Welcome to tutorialspoint').toUpperCase()");
message = (String) exp.getValue();
System.out.println(message);
}
}
Spring SpEL - EvaluationContext
EvaluationContext 是 Spring SpEL 的一个接口,它用于在上下文中执行一个表达式字符串。在表达式评估过程中遇到的引用将在该上下文中解析。
Syntax
以下是一个创建 EvaluationContext 并使用其对象来获取值示例。
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'name'");
EvaluationContext context = new StandardEvaluationContext(employee);
String name = (String) exp.getValue();
它应按如下方式打印结果:
Mahesh
此处的结果是在员工对象 Mahesh 的字段 name 的值。StandardEvaluationContext 类指定了评估表达式的对象。 StandardEvaluationContext在上下文对象创建后无法更改。它缓存状态,并允许快速执行表达式评估。以下示例显示各种用例。
Example
以下示例显示一个类 MainApp。
让我们更新在 Spring SpEL - Create Project 章节中创建的项目。我们正在添加以下文件−
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) {
Employee employee = new Employee();
employee.setId(1);
employee.setName("Mahesh");
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext(employee);
Expression exp = parser.parseExpression("name");
// evaluate object using context
String name = (String) exp.getValue(context);
System.out.println(name);
Employee employee1 = new Employee();
employee1.setId(2);
employee1.setName("Rita");
// evaluate object directly
name = (String) exp.getValue(employee1);
System.out.println(name);
exp = parser.parseExpression("id > 1");
// evaluate object using context
boolean result = exp.getValue(context, Boolean.class);
System.out.println(result); // evaluates to false
result = exp.getValue(employee1, Boolean.class);
System.out.println(result); // evaluates to true
}
}
Spring SpEL - XML Based Configuration
SpEL 表达式可用于基于 XML 的 Bean 配置
Syntax
以下是使用 XML 配置中表达式的示例。
<bean id="randomNumberGenerator" class="com.tutorialspoint.RandomNumberGenerator">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
</bean>
在此,我们已指定要使用 Math.random() 方法填入的属性。对于类,其名称应该是完全限定的。我们还可以使用 systemProperties 作为系统变量。它是一个内置变量。
<property name="country" value="#{ systemProperties['user.country'] }"/>
我们还可以在 SpEL 表达式中使用另一个 Bean,如下所示:
<property name="id" value="#{ randomNumberGenerator.randomNumber }"/>
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
RandomNumberGenerator.java − 一个随机数生成器类。
-
Employee.java - 一个员工类。
-
MainApp.java - 要运行和测试的主应用。
-
applicationcontext.xml − Beans 配置文件。
下面是 RandomNumberGenerator.java 文件的内容 −
package com.tutorialspoint;
public class RandomNumberGenerator {
private int randomNumber;
public int getRandomNumber() {
return randomNumber;
}
public void setRandomNumber(int randomNumber) {
this.randomNumber = randomNumber;
}
}
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private int id;
private String name;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "[" + id + ", " + name + ", " + country + "]";
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");
Employee employee = (Employee) applicationContext.getBean("employee");
System.out.println(employee);
}
}
下面是 applicationcontext.xml 文件的内容 −
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="randomNumberGenerator" class="com.tutorialspoint.RandomNumberGenerator">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
</bean>
<bean id="employee" class="com.tutorialspoint.Employee">
<property name="id" value="#{ randomNumberGenerator.randomNumber }"/>
<property name="country" value="#{ systemProperties['user.country'] }"/>
<property name="name" value="Mahesh"/>
</bean>
</beans>
Spring SpEL - Annotation Based Configuration
SpEL 表达式可以在基于注解的 bean 配置中使用
Syntax
以下是使用基于注解的配置中的表达式的一个示例。
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private int id;
这里我们使用 @Value 注解,我们在一个属性上指定了一个 SpEL 表达式。类似地,我们也可以在 setter 方法中、在构造器中以及在自动布线期间指定 SpEL 表达式。
@Value("#{ systemProperties['user.country'] }")
public void setCountry(String country) {
this.country = country;
}
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java - 一个员工类。
-
AppConfig.java - 一个配置类。
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Employee {
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private int id;
private String name;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
@Value("Mahesh")
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
@Value("#{ systemProperties['user.country'] }")
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "[" + id + ", " + name + ", " + country + "]";
}
}
以下是 AppConfig.java 文件的内容 -
package com.tutorialspoint;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.tutorialspoint")
public class AppConfig {
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();
Employee emp = context.getBean(Employee.class);
System.out.println(emp);
}
}
Spring SpEL - Literal Expression
SpEL 表达式支持以下类型的文本常量 -
-
Strings - 单引号分隔的字符串。要使用单引号,请在其周围加上另一个单引号。
-
Numeric - 支持 int、real 和 hex 表达式。
-
boolean
-
null
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class MainApp {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
// parse a simple text
String message = (String) parser.parseExpression("'Tutorialspoint'").getValue();
System.out.println(message);
// parse a double from exponential expression
double avogadros = (Double) parser.parseExpression("6.0221415E+23").getValue();
System.out.println(avogadros);
// parse an int value from Hexadecimal expression
int intValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
System.out.println(intValue);
// parse a boolean
boolean booleanValue = (Boolean) parser.parseExpression("true").getValue();
System.out.println(booleanValue);
// parse a null object
Object nullValue = parser.parseExpression("null").getValue();
System.out.println(nullValue);
}
}
Spring SpEL - Properties
SpEL 表达式支持访问对象的属性。
-
我们也可以在 SpEL 表达式中访问嵌套属性。
-
在 SpEL 表达式中,属性的首字母不区分大小写。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
import java.util.Date;
public class Employee {
private int id;
private String name;
private Date dateOfBirth;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@Override
public String toString() {
return "[" + id + ", " + name + ", " + dateOfBirth + "]";
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
employee.setId(1);
employee.setName("Mahesh");
employee.setDateOfBirth(new SimpleDateFormat("YYYY-MM-DD").parse("1985-12-01"));
EvaluationContext context = new StandardEvaluationContext(employee);
int birthYear = (Integer) parser.parseExpression("dateOfBirth.Year + 1900").getValue(context);
System.out.println(birthYear);
String name = (String) parser.parseExpression("name").getValue(context);
System.out.println(name);
}
}
Spring SpEL - Array
SpEL 表达式支持访问数组并使用对象数组的索引。
-
我们也可以在 SpEL 表达式中访问嵌套数组。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
Dept.java − Department class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String[] awards;
public String[] getAwards() {
return awards;
}
public void setAwards(String[] awards) {
this.awards = awards;
}
}
以下 Dept.java 文件的内容:
package com.tutorialspoint;
public class Dept {
private Employee[] employees;
public Employee[] getEmployees() {
return employees;
}
public void setEmployees(Employee[] employees) {
this.employees = employees;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
String[] awards = {"Star of the Month", "Champion", "Accelerator"};
employee.setAwards(awards);
Employee[] employees = { employee };
Dept dept = new Dept();
dept.setEmployees(employees);
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// evaluates to "Accelerator"
String award = parser.parseExpression("awards[2]").getValue(employeeContext, String.class);
System.out.println(award);
EvaluationContext deptContext = new StandardEvaluationContext(dept);
// evaluates to "Champion"
award = parser.parseExpression("employees[0].awards[1]").getValue(deptContext, String.class);
System.out.println(award);
}
}
Spring SpEL - List
SpEL 表达式支持访问列表并使用对象列表的索引。
-
我们也可以在 SpEL 表达式中访问嵌套列表。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
Dept.java − Department class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private List<String> awards;
public List<String> getAwards() {
return awards;
}
public void setAwards(List<String> awards) {
this.awards = awards;
}
}
以下 Dept.java 文件的内容:
package com.tutorialspoint;
public class Dept {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.Arrays;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
employee.setAwards(Arrays.asList("Star of the Month", "Champion", "Accelerator"));
Dept dept = new Dept();
dept.setEmployees(Arrays.asList(employee));
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// evaluates to "Accelerator"
String award = parser.parseExpression("awards.get(2)").getValue(employeeContext, String.class);
System.out.println(award);
EvaluationContext deptContext = new StandardEvaluationContext(dept);
// evaluates to "Champion"
award = parser.parseExpression("employees.get(0).awards.get(1)").getValue(deptContext, String.class);
System.out.println(award);
}
}
Spring SpEL - Map
SpEL 表达式支持访问映射。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
import java.util.Map;
public class Employee {
private Map<String, String> offices;
public Map<String, String> getOffices() {
return offices;
}
public void setOffices(Map<String, String> offices) {
this.offices = offices;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
Map<String, String> officeMap = new HashMap();
officeMap.put("IN", "Hyderabad");
officeMap.put("UK", "London");
employee.setOffices(officeMap);
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// evaluates to "Hyderabad"
String city = parser.parseExpression("offices['IN']").getValue(employeeContext, String.class);
System.out.println(city);
}
}
Spring SpEL - Methods
SpEL 表达式支持访问某个对象的函数。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private List<String> awards;
public List<String> getAwards() {
return awards;
}
public void setAwards(List<String> awards) {
this.awards = awards;
}
public boolean isAwardee() {
return awards != null && awards.size() > 0;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.Arrays;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
employee.setAwards(Arrays.asList("Star of the Month", "Champion", "Accelerator"));
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// string literal, evaluates to "t"
String t = parser.parseExpression("'Tutorials'.substring(2, 3)").getValue(String.class);
System.out.println(t);
// evaluates to true
boolean isAwardee = parser.parseExpression("isAwardee()").getValue(employeeContext, Boolean.class);
System.out.println(isAwardee);
}
}
Spring SpEL - Relational Operators
SpEL 表达式支持关系运算符,例如 <、>、等于等。它也支持 instance of 和 matches 运算符。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
// evaluates to true
boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class);
System.out.println(result);
// evaluates to false
result = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
System.out.println(result);
// evaluates to true
result = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
System.out.println(result);
// evaluates to false
result = parser.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class);
System.out.println(result);
// evaluates to false
result = parser.parseExpression("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
System.out.println(result);
}
}
Spring SpEL - Logical Operators
SpEL 表达式支持逻辑运算符,如 AND、OR 和 NOT。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
// evaluates to true
boolean result = parser.parseExpression("true and true").getValue(Boolean.class);
System.out.println(result);
// evaluates to true
result = parser.parseExpression("true or false").getValue(Boolean.class);
System.out.println(result);
// evaluates to false
result = parser.parseExpression("!true").getValue(Boolean.class);
System.out.println(result);
}
}
Spring SpEL - Mathematical Operators
SpEL 表达式支持数学运算符,例如 +、-、* 等。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
// evaluates to 5
int result = parser.parseExpression("3 + 2").getValue(Integer.class);
System.out.println(result);
// evaluates to 1
result = parser.parseExpression("3 - 2").getValue(Integer.class);
System.out.println(result);
// evaluates to 6
result = parser.parseExpression("3 * 2").getValue(Integer.class);
System.out.println(result);
// evaluates to 1
result = parser.parseExpression("3 / 2").getValue(Integer.class);
System.out.println(result);
// evaluates to 1
result = parser.parseExpression("3 % 2").getValue(Integer.class);
System.out.println(result);
// follow operator precedence, evaluate to -9
result = parser.parseExpression("1+2-3*4").getValue(Integer.class);
System.out.println(result);
}
}
Spring SpEL - Assignment Operator
SpEL 表达式支持使用 setValue() 方法以及使用赋值运算符来分配属性。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee object.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// Using setValue
parser.parseExpression("name").setValue(employeeContext, "Mahesh");
String result = parser.parseExpression("name").getValue(employeeContext, String.class);
System.out.println(result);
// Using assignment operator
result = parser.parseExpression("Name = 'Robert'").getValue(employeeContext, String.class);
System.out.println(result);
}
}
Spring SpEL - Ternary Operator
SpEL 表达式支持三元运算符来执行 if-then-else 逻辑。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
String result = parser.parseExpression("true ? 'Yes' : 'No'").getValue(String.class);
System.out.println(result);
result = parser.parseExpression("false ? 'Yes' : 'No'").getValue(String.class);
System.out.println(result);
}
}
Spring SpEL - Elvis Operator
SpEL 表达式支持 Elvis 运算符,它是一种三元运算符的简写形式。
// Using ternary operator
String result = name != null ? name: "unknown";
// Using Elvis Operator
result = name?:"unknown";
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// Evaluates to "unknown"
String result = parser.parseExpression("name?:'unknown'").getValue(employeeContext, String.class);
System.out.println(result);
employee.setName("Mahesh");
// Evaluates to "Mahesh"
result = parser.parseExpression("name?:'unknown'").getValue(employeeContext, String.class);
System.out.println(result);
}
}
Spring SpEL - Safe Navigation Operator
SpEL 表达式支持安全导航运算符,用于避免 NullPointerException。
int length = parser.parseExpression("name?.length").getValue(context, Integer.class);
如果这里 name 为空,那么表达式不会抛出空指针异常。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee();
EvaluationContext employeeContext = new StandardEvaluationContext(employee);
// Evaluates to null but will not throw null pointer exception during parseExpression
String result = parser.parseExpression("name?.strip()").getValue(employeeContext, String.class);
System.out.println(result);
employee.setName(" Mahesh ");
// Evaluates to "Mahesh"
result = parser.parseExpression("name?.strip()").getValue(employeeContext, String.class);
System.out.println(result);
}
}
Spring SpEL - Collection Selection
SpEL 表达式支持集合选择,这是一种非常强大的表达式,允许通过从源集合中选择条目来将源集合转换为另一个集合。
Syntax
?[selectionExpresion]
以下示例展示这种用法。
List<Employee> list = (List<Employee>)
parser.parseExpression("employees.?[country == 'USA']").getValue(deptContext);
这里 SpEL 仅从 employees 列表中返回 country 为 USA 的那些 employees。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
Dept.java − Department class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
private String country;
public Employee(String name, String country) {
this.name = name;
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String toString() {
return "[" +name+ ", "+country + "]";
}
}
以下 Dept.java 文件的内容:
package com.tutorialspoint;
import java.util.List;
public class Dept {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee1 = new Employee("Robert", "USA");
Employee employee2 = new Employee("Julie", "USA");
Employee employee3 = new Employee("Ramesh", "India");
List<Employee> employees = new ArrayList<Employee>();
employees.add(employee1);
employees.add(employee2);
employees.add(employee3);
Dept dept = new Dept();
dept.setEmployees(employees);
EvaluationContext deptContext = new StandardEvaluationContext(dept);
// Select list of employees who are living in USA
List<Employee> list = (List<Employee>)
parser.parseExpression("employees.?[country == 'USA']").getValue(deptContext);
System.out.println(list);
}
}
Spring SpEL - Collection Projection
SpEL 表达式支持集合投影,这是一种非常强大的表达式,允许评估子表达式并在结果中返回一个新集合。
Syntax
![projectionExpresion]
以下示例展示这种用法。
List<String> list = (List<String>)
parser.parseExpression("employees.![country]").getValue(deptContext);
这里 SpEL 仅从 employees 列表中返回 country 为 USA 的那些 employees。
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
Dept.java − Department class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
private String country;
public Employee(String name, String country) {
this.name = name;
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String toString() {
return "[" +name+ ", "+country + "]";
}
}
以下 Dept.java 文件的内容:
package com.tutorialspoint;
import java.util.List;
public class Dept {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee1 = new Employee("Robert", "USA");
Employee employee2 = new Employee("Julie", "USA");
Employee employee3 = new Employee("Ramesh", "India");
List<Employee> employees = new ArrayList<Employee>();
employees.add(employee1);
employees.add(employee2);
employees.add(employee3);
Dept dept = new Dept();
dept.setEmployees(employees);
EvaluationContext deptContext = new StandardEvaluationContext(dept);
// Select list of countries
List<String> list = (List<String>)
parser.parseExpression("employees.![country]").getValue(deptContext);
System.out.println(list);
}
}
Spring SpEL - Constructor
SpEL 表达式支持使用 new 运算符在表达式中创建对象。我们需要传递类的完全限定名称。
Syntax
Employee robert = parser.parseExpression("new com.tutorialspoint.Employee('Robert','USA')").getValue(Employee.class);
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
Dept.java − Department class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
private String country;
public Employee(String name, String country) {
this.name = name;
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String toString() {
return "[" +name+ ", "+country + "]";
}
}
以下 Dept.java 文件的内容:
package com.tutorialspoint;
import java.util.List;
public class Dept {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public String toString() {
return "[" + employees.toString() + "]";
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
List<Employee> employees = new ArrayList<Employee>();
Employee robert = parser.parseExpression("new com.tutorialspoint.Employee('Robert','USA')")
.getValue(Employee.class);
employees.add(robert);
Dept dept = new Dept();
dept.setEmployees(employees);
System.out.println(dept);
EvaluationContext deptContext = new StandardEvaluationContext(dept);
parser.parseExpression("employees.add(new com.tutorialspoint.Employee('Julie','USA'))")
.getValue(deptContext);
System.out.println(dept);
}
}
Spring SpEL - Variables
SpEL 表达式允许使用 #variable-name 语法创建和使用特定于表达式的变量。使用 EvaluationContext 中的 setVariable 设置变量。还有两种内置变量,#this 和 #root。#this 变量始终引用当前评估对象,而 #root 变量引用评估上下文的根对象。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
Employee.java − Employee class.
-
MainApp.java - 要运行和测试的主应用。
以下 Employee.java 文件的内容:
package com.tutorialspoint;
public class Employee {
private String name;
private String country;
public Employee(String name, String country) {
this.name = name;
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String toString() {
return "[" +name+ ", "+country + "]";
}
}
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException {
ExpressionParser parser = new SpelExpressionParser();
Employee employee = new Employee("Mahesh", "INDIA");
EvaluationContext context = new StandardEvaluationContext(employee);
context.setVariable("newName", "Mahesh Parashar");
parser.parseExpression("Name = #newName").getValue(context);
// Evaluate to "Mahesh Parashar"
System.out.println(employee.getName());
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
context.setVariable("primes",primes);
List<Integer> filteredList =
(List<Integer>) parser.parseExpression("#primes.?[#this>10]").getValue(context);
// Evaluate to [11, 13, 17], prime numbers greater than 10
System.out.println(filteredList);
}
}
Spring SpEL - Functions
SpEL 表达式允许使用 #function-name 语法创建和使用特定于表达式的函数。使用 EvaluationContext 中的 registerFunction 设置函数。
Syntax
context.registerFunction("reverse", MainApp.class.getDeclaredMethod("reverse", new Class[] { String.class }));
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class MainApp {
public static void main(String[] args) throws ParseException, NoSuchMethodException, SecurityException {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.registerFunction("reverse",
MainApp.class.getDeclaredMethod("reverse", new Class[] { String.class }));
String reverseString=parser.parseExpression("#reverse('main')").getValue(context, String.class);
System.out.println(reverseString);
}
public static String reverse(String input) {
StringBuilder backwards = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
backwards.append(input.charAt(input.length() - 1 - i));
}
return backwards.toString();
}
}
Spring SpEL - Expression Templating
SpEL 表达式允许将文本常量与评估块混合。每个评估块都应适当地加上前缀和后缀。标准选择是使用 #{}. org.springframework.expression.common. TemplateParserContextTemplateParserContext 使用相同的方式。
Syntax
String result = parser.parseExpression("Random number : #{T(java.lang.Math).random()
* 100}", new TemplateParserContext()).getValue(String.class);
以下示例显示了各种使用案例。
Example
让我们更新在 Spring SpEL - Create Project 章节创建的项目。我们添加/更新了以下文件:
-
MainApp.java - 要运行和测试的主应用。
以下 MainApp.java 文件的内容:
package com.tutorialspoint;
import java.text.ParseException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class MainApp {
public static void main(String[] args) throws ParseException, NoSuchMethodException, SecurityException {
ExpressionParser parser = new SpelExpressionParser();
String result=parser.parseExpression("Random number : #{T(java.lang.Math).random()
* 100}", new TemplateParserContext()).getValue(String.class);
System.out.println(result);
}
}