博客
关于我
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 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    MySql 手动执行主从备份
    查看>>
    Mysql 批量修改四种方式效率对比(一)
    查看>>
    mysql 批量插入
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>
    Mysql 拼接多个字段作为查询条件查询方法
    查看>>
    mysql 排序id_mysql如何按特定id排序
    查看>>
    Mysql 提示:Communication link failure
    查看>>
    mysql 插入是否成功_PDO mysql:如何知道插入是否成功
    查看>>
    Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
    查看>>
    mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
    查看>>
    mysql 数据库备份及ibdata1的瘦身
    查看>>
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    MySQL 数据库设计总结
    查看>>
    Mysql 数据库重置ID排序
    查看>>
    Mysql 数据类型一日期
    查看>>