博客
关于我
Spring 5 中文解析之核心篇-表达式(SpEL)
阅读量:711 次
发布时间:2019-03-21

本文共 3968 字,大约阅读时间需要 13 分钟。

Spring 表达式语言(SpEL)入门介绍

Spring Expression Language(简称 SpEL)是一种强大且灵活的表达式语言,由 Spring Framework 开发,广泛应用于运行时对象的查询和操作。它在 Spring 社区中的多个产品组合中都有广泛的支持,是定义 Bean 的表达方式的一种重要工具。以下将详细介绍 SpEL 的基本功能、使用方法以及在实际应用中的示例。


SpEL 的基本特性

SpEL 的语法类似于 Java 的 EL(Expression Language),但扩展了许多功能,主要包括以下几个方面:

1. 方法调用

SpEL 支持在表达式中直接调用方法,例如:

ExpressionParser parser = new SpelExpressionParser();Expression exp = parser.parseExpression("'Hello World'.concat('!')");String message = (String) exp.getValue();

输出结果为 "Hello World!"。

2. 属性访问

属性可以通过点号访问,例如:

ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();Inventor tesla = new Inventor("Nikola Tesla", "Serbian");String name = (String) parser.parseExpression("name").getValue(tesla);// 结果:name == "Nikola Tesla"

3. 数字和字符串操作

支持基本的数字运算、四舍五入、指数运算等,以及字符串的构造函数操作,例如:

ExpressionParser parser = new SpelExpressionParser();String upperCase = parser.parseExpression("new String('hello world').toUpperCase()").getValue(String.class);// 结果:"HELLO WORLD"

4. 类型转换

SpEL 支持通过 ConversionService 进行类型转换,例如:

class Simple {    public List
booleanList = new ArrayList<>();}Simple simple = new Simple();simple.booleanList.add(true); EVALUATION_CONTEXT配置为只读访问模式:EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();parser.parseExpression("booleanList[0]").setValue(context, simple, "false")// 结果:trueBoolean b = simple.booleanList.get(0);

5. 集合和映射操作

支持内联列表和映射,例如:

ExpressionParser parser = new SpelExpressionParser();List numbers = parser.parseExpression("{1,2,3,4}").getValue(List.class);List
list = parser.parseExpression("{'a','b'}").getValue(List.class);

SpEL 的主要用法

1. 在 Bean 定义中的应用

在 XML 或注解配置中使用 SpEL 表达式指定属性值或构造函数参数,例如:

或者使用注解:

public class ExampleBean {    @Value("#{ systemProperties['user.region'] }")    private String defaultLocale;}

2. 作为表达式评估工具

通过 SpEL 表达式可以对对象进行各种操作,例如评估布尔逻辑:

ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();boolean isMember = parser.parseExpression("isMember('Nikola Tesla')").getValue(context, Boolean.class);

3. 方法调用和变量使用

可以通过 #variable 来引用变量,并在表达式中使用安全导航操作符避免 NullPointer:

EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();context.setVariable("queryName", "Nikola Tesla");Expression expression = parser.parseExpression("Name == 'IEEE' and isMember(#queryName)");String result = parser.parseExpression(expression).getValue(context, String.class);

SpEL 的核心组件

1. 解析器(ExpressionParser)

负责解析 SpEL 表达式字符串,例如:

ExpressionParser parser = new SpelExpressionParser();Expression exp = parser.parseExpression("'Hello World'");Object value = exp.getValue(); // 返回 "Hello World"

2. 评估上下文(EvaluationContext)

用于管理评估过程中的变量和类型转换策略。主要实现包括 SimpleEvaluationContextStandardEvaluationContext

3. 转换服务(ConversionService)

默认使用 Spring 内核的转换服务,可自定义扩展以支持特定类型转换。


SpEL 的编译器

从 Spring 4.1 开始,SpEL 提供了编译器来提高表达式评估的性能。编译器关心项目的动态性和稳定性,适用于高性能需求的场景,但无法编译所有类型复杂的表达式,主要适用于以下情况:

编译模式

  • OFF:少互动时使用。
  • IMMEDIATE:在第一次评估后立即编译。
  • MIXED:在多次评估后动态切换编译模式。

配置方式

通过 SpelParserConfiguration 配置编译模式和类加载器,例如:

SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, this.getClass().getClassLoader());SpelExpressionParser parser = new SpelExpressionParser(config);

SpEL 的实际应用示例

示例 1:评估属性值

Inventor inventor = new Inventor("Nikola Tesla");EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();String fullName = parser.parseExpression("name").getValue(inventor, String.class);// 结果:"Nikola Tesla"

示例 2:复杂表达式

List
numbers = parser.parseExpression("8 / 5 % 2").getValue(List.class);// 结果:[1]

SpEL 的优势

  • 灵活性:支持多种操作,包括方法调用、属性访问、布尔逻辑、集合操作等。
  • 安全性:通过安全导航操作符避免 NullPointer 错误。
  • 高性能:使用编译器大幅提升评估性能。
  • 通用性:适用于 XML、注解配置以及其他 Spring 组件。

  • 总结

    SpEL 是 Spring 表达式语言的核心工具,广泛应用于对象的动态操作、属性访问以及数据绑定。通过合理使用 SpEL,开发者可以大大提升代码的灵活性和 maintainability。如果需要更详细的技术文档,可以参考 Spring 官方资料或相关技术博客。

    转载地址:http://oldrz.baihongyu.com/

    你可能感兴趣的文章
    mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
    查看>>
    mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
    查看>>
    MySQL 8.0 恢复孤立文件每表ibd文件
    查看>>
    MySQL 8.0开始Group by不再排序
    查看>>
    mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
    查看>>
    multi swiper bug solution
    查看>>
    MySQL Binlog 日志监听与 Spring 集成实战
    查看>>
    MySQL binlog三种模式
    查看>>
    multi-angle cosine and sines
    查看>>
    Mysql Can't connect to MySQL server
    查看>>
    mysql case when 乱码_Mysql CASE WHEN 用法
    查看>>
    Multicast1
    查看>>
    mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
    查看>>
    MySQL Cluster 7.0.36 发布
    查看>>
    Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
    查看>>
    MySQL Cluster与MGR集群实战
    查看>>
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    查看>>
    mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
    查看>>
    Multiple websites on single instance of IIS
    查看>>
    mysql CONCAT()函数拼接有NULL
    查看>>