spring使用spring表达式(springel)(代码片段)

ooo0 ooo0     2022-12-17     296

关键词:

  Spring还提供了更灵活的注入方式,那就是Spring表达式,实际上Spring EL远比以上注入方式强大,我们需要学习它。Spring EL拥有很多功能。
  使用Bean的id来引用Bean。
  •调用指定对象的方法和访问对象的属性。
  •进行运算。
  •提供正则表达式进行匹配。
  •集合配置。
  这些都是Spring表达式的内容,使用Spring表达式可以获得比使用Properties文件更为强大的装配功能,只是有时候为了方便测试可以使用Spring EL定义的解析类进行测试,为此我们先来认识它们。

Spring EL相关的类

  简要介绍Spring EL的相关类,以便我们进行测试和理解。首先是ExpressionParser接口,它是一个表达式的解析接口,既然是一个接口,那么它就不具备任何具体的功能,显然Spring会提供更多的实现类

  技术图片

 

  代码清单:举例说明Spring EL的使用

//表达式解析器
ExpressionParser parser = new SpelExpressionParser();
// 设置表达式
Expression exp = parser.parseExpression("‘hello world‘");
String str = (String) exp.getValue();
System.out.println(str);
//通过EL访问普通方法
exp = parser.parseExpression("‘hello world‘.charAt(0)");
char ch = (Character) exp.getValue();
System.out.println(ch);
//通过EL访问的getter方法
exp = parser.parseExpression("‘hello world‘.bytes");
byte[] bytes = (byte[]) exp.getValue();
System.out.println(bytes);
//通过EL访问属性,相当于"hello world".getBytes().length
exp = parser.parseExpression("‘hello world‘.bytes.length");
int length = (Integer) exp.getValue();
System.out.println(length);
exp = parser.parseExpression("new String(‘abc‘)");
String abc = (String) exp.getValue();
System.out.println(abc);

 

//表达式解析器
ExpressionParser parser = new SpelExpressionParser();
//创建角色对象
Role2 role = new Role2(1L, "role_name", "note");
Expression exp = parser.parseExpression("note");
//相当于从role中获取备注信息
String note = (String) exp.getValue(role);
System.out.println(note);
//变量环境类,并且将角色对象role作为其根节点
EvaluationContext ctx = new StandardEvaluationContext(role);
//变量环境类操作根节点
parser.parseExpression("note").setValue(ctx, "new_note");
//获取备注,这里的String.class指明,我们希望返回的是一个字符串
note = parser.parseExpression("note").getValue(ctx, String.class);
System.out.println(note);
//调用getRoleName方法
String roleName = parser.parseExpression("getRoleName()").getValue(ctx, String.class);
System.out.println(roleName);
//新增环境变量
List<String> list = new ArrayList<String>();
list.add("value1");
list.add("value2");
//给变量环境增加变量
ctx.setVariable("list", list);
//通过表达式去读/写环境变量的值
parser.parseExpression("#list[1]").setValue(ctx, "update_value2");
System.out.println(parser.parseExpression("#list[1]").getValue(ctx));

 

  EvaluationContext使用了它的实现类StandardEvaluationContext,进行了实例化,在构造方法中将角色对象传递给它了,那么估值内容就会基于这个类进行解析。所以后面表达式的setValue和getValue方法都把这个估值内容传递进去,这样就能够读/写根节点的内容了,并且通过getRole()的例子,还可以知道它甚至能够支持方法的调用。为了更加灵活,估值内容还支持了其他变量的新增和操作,正如代码中创建了一个List,并且把List用估值内容的setVariable方法设置,其键为"list",这样就允许我们在表达式里面通过#list去引用它,而给出的下标1,则是代表引用List的第二个元素(list是以下标0标识第一个元素的)。
  上面介绍了Spring具有对表达式的解析功能,Spring EL最重要的功能就是对Bean属性进行注入,让我们以注解的方式为主去学习它们。

Bean的属性和方法

  使用注解的方式需要用到注解@Value,在属性文件的读取中使用的是“$”,而在Spring EL中则使用“#”。下面以角色类为例进行讨论,我们可以这样初始化它的属性,如代码清单所示。
  代码清单:使用Spring EL初始化角色类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("role2")
public class Role2 

//赋值long型
@Value("#2")
private Long id;
//字符串赋值
@Value("#‘role_name_2‘")
private String roleName;
//字符串赋值
@Value("#‘note_2‘")
private String note;

 

  代码清单:通过Spring EL引用role的属性,调用其方法

@Component("elBean")
public class ElBean 

//通过beanName获取bean,然后注入
@Value("#role2")
private Role2 role2;

//获取bean的属性id
@Value("#role2.id")
private Long id;

//调用bean的getNote方法,获取角色名称
// @Value("#role.getNote().toString()")
@Value("#role2.getNote()?.toString()")
private String note;

@Value("#T(Math).PI")
private double pi;

@Value("#T(Math).random()")
private double random;

@Value("#role.id+1")
private int num;

 

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig3.class);
Role2 role2 = context.getBean(Role2.class);
System.out.println(role2.toString());
ElBean elBean = context.getBean(ElBean.class);
System.out.println(elBean.toString());

 

使用类的静态常量和方法  

  有时候我们可能希望使用一些静态方法和常量,比如圆周率π,而在Java中就是Math类的PI常量了,需要注入它十分简单,在ElBean中如同下面一样操作就可以了:
  @Value("#T(Math).PI")
  private double pi;
  这里的Math代表的是java.lang.*包下的Math类。当在Java代码中使用该包是不需要先使用import关键字引入的,对于Spring EL也是如此。如果在Spring中使用一个非该包的内容,那么要给出该类的全限定名,需要写成类似这样:
  @Value("#T(java.lang.Math).PI")
  private double pi;
  同样,有时候使用Math类的静态方法去生产随机数(0到1之间的随机双精度数字),这个时候就需要使用它的random方法了,比如:
  @Value("#T(Math).random()")
  private double random;
  这样就可以通过调用类的静态方法加载对应的数据了。

Spring EL运算

  上面讨论了如何获取值,除此之外Spring EL还可以进行运算,比如在ElBean上增加一个数字num,其值默认为要求是角色编号(id)+1,那么我们就可以写成:

  @Value("#role.id+1")
  private int num;
  有时候“+”运算符也可以运用在字符串的连接上,比如下面的这个字段,把角色对象中的属性roleName和note相连:
  @Value("#role.roleName + role.note")
  private String str;
  这样就能够得到一个角色名称和备注相连接的字符串。比较两个值是否相等,比如角色id是否为1,角色名称是否为"role_name_001"。数字和字符串都可以使用“eq”或者“==”进行相等比较。除此之外,还有大于、小于等数学运算,比如:
  @Value("#role.id == 1")
  private boolean equalNum;
  @Value("#role.note eq ‘note_1‘")
  private boolean eqaulString;
  @Value("#role.id > 2")
  private boolean greater;
  @Value("#role.id < 2")
  private boolean less;
  在Java中,也许你会怀念三目运算,比如,如果角色编号大于1,那么取值5,否则取值1,那么在Java中可以写成:
  int max = (role.getId()>1? 5:1);
  如果角色的备注为空,我们给它一个默认的初始值“note”,使用Java则写成:  
  String defaultString = (role.getNote() == null? "hello" : role.getNote());
  下面让我们通过String EL去实现上述的功能。
  @Value("#role.id > 1 ? 5 : 1")
  private int max;
  @Value("#role.note?: ‘hello‘")
  private String defaultString;
  实际上Spring EL的功能远不止这些,上面只介绍了一些最基础、最常用的功能,熟练运用它还需要读者们多动手实践。

 

 

文章来源:ssm10.10

在自定义注解中使用 spring 安全表达式

】在自定义注解中使用spring安全表达式【英文标题】:Usespringsecurityexpressionsincustomannotation【发布时间】:2017-01-1101:36:30【问题描述】:您好,我有一个带有SpringBoot+SpringSecurity的项目。我正在构建一个我这样定义的自定义注释:@... 查看详情

如何从 db 加载 cron 表达式并使用 Spring 重新安排它?

】如何从db加载cron表达式并使用Spring重新安排它?【英文标题】:HowtoloadacronexpressionfromdbandrescheduleitwithSpring?【发布时间】:2015-11-1100:59:23【问题描述】:我正在使用Spring调度在我的应用程序中进行批处理。@Scheduled(cron="$batch.name... 查看详情

spring简介以及简单使用

...sp;后面这些连接参数会单独写在另一个文件中,通过spring表达式来赋值。总之Spring框架改变了传统的创建对象和管理对象的方式,把代码换成了配置 查看详情

spring表达式语言:spel语法(代码片段)

Spring表达式语言简称:SpEL,SpEL既可以独立于Spring容器使用,,也可以在Spring配置文件中使用,这样就大大简化了Spring的Bean配置,给配置文件起到了“减肥”的作用,下面开始总结SpEL语法1:直接量... 查看详情

带有@Value 的 Spring 表达式语言 (SpEL):美元与哈希($ 与 #)

】带有@Value的Spring表达式语言(SpEL):美元与哈希($与#)【英文标题】:SpringExpressionLanguage(SpEL)with@Value:dollarvs.hash($vs.#)【发布时间】:2011-07-1609:50:31【问题描述】:与#...相比,何时使用$...有点困惑。Spring的文档只使用了#...,但... 查看详情

使用正则表达式的 Spring 请求映射,如 javax.ws.rs

】使用正则表达式的Spring请求映射,如javax.ws.rs【英文标题】:Springrequestmappingwithregexlikeinjavax.ws.rs【发布时间】:2020-07-1523:21:04【问题描述】:我正在尝试将thisGoogleAppEnginemavenserverrepository重写为Spring。我的网址映射有问题。Maven... 查看详情

spring/maven/mybatis配置文件结合properties文件使用

...置项写入到这个文件,然后在Spring的XML配置文件中使用EL表达式去获取。这种方式不只Spring可以使用,同样MyBatis也可以使用,只不过加载的方式不一样,但是获取值同样是EL表达式。具体的参考官方文档。properties语法参考:https:... 查看详情

前方高能预警!阿里大佬出品“spring实战学习笔记”震撼来袭

...,而且Spring3引入了强大的新特性,例如SpEL、Spring表达式语言、loC容器的新注解以及用户急需的对REST的支持。无论你是刚刚接触Spring还是被Spring3.0的新特性所吸引,这份笔记都是掌握Spring的最佳选择。本笔记涵盖的主... 查看详情

spring专题「实战系列」针对spring注解@conditionalonexpression详细使用说明(代码片段)

...0c;配置参数是否存在或者有某个值而言,这个依赖SPEL表达式的,就显得更加的高级了;其主要就是执行Spel表达式,根据返回的true/false来判断是否满足条件。至于SPEL是什么东西,下面以一个简单的demo进行演示... 查看详情

spring专题「实战系列」针对spring注解@conditionalonexpression详细使用说明(代码片段)

...0c;配置参数是否存在或者有某个值而言,这个依赖SPEL表达式的,就显得更加的高级了;其主要就是执行Spel表达式,根据返回的true/false来判断是否满足条件。至于SPEL是什么东西,下面以一个简单的demo进行演示... 查看详情

前方高能预警!阿里大佬出品“spring实战学习笔记”震撼来袭!(代码片段)

...,而且Spring3引入了强大的新特性,例如SpEL、Spring表达式语言、loC容器的新注解以及用户急需的对REST的支持。无论你是刚刚接触Spring还是被Spring3.0的新特性所吸引,这份笔记都是掌握Spring的最佳选择。本笔记涵盖的主... 查看详情

spring_spel

...nbsp; 简单介绍SpEL的概念和使用  二、概念Spring表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。语法类似于EL:SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpELSp... 查看详情

直接使用返回 spring security 的内置表达式的方法

】直接使用返回springsecurity的内置表达式的方法【英文标题】:Usemethodsdirectlythatbackspringsecurity\'sbuilt-inexpressions【发布时间】:2012-10-0510:51:59【问题描述】:我想在我的控制器中使用一些与built-inexpressionsprovidedbySpringSecurity类似的(... 查看详情

spring动态代理开发的切入点表达式

spring动态代理开发的切入点表达式在前面总结了spring的动态代理开发的步骤,指定增强类(额外功能)的使用,那有了功能,还需要指定使用功能的地方,就需要切入表达式来指定切入的地点1,演示文件结构和类实现先看下文... 查看详情

spring切入点表达式常用写法

Spring切入点表达式常用写法自从使用AspectJ风格切面配置,使得Spring的切面配置大大简化,但是AspectJ是另外一个开源项目,其规则表达式的语法也稍稍有些怪异。下面给出一些常见示例的写法:比如,下面是一个对Service包上所有... 查看详情

Spring Security antMatchers 正则表达式

】SpringSecurityantMatchers正则表达式【英文标题】:SpringSecurityantMatchersRegex【发布时间】:2018-07-1705:14:45【问题描述】:我的spring安全配置中已经有antmatchers()使用通配符。我需要从这个通配符中过滤掉“表格”。这是我的原始代码... 查看详情

在 JavaScript 中的 Thymeleaf 中使用 Spring Security 转义表达式

】在JavaScript中的Thymeleaf中使用SpringSecurity转义表达式【英文标题】:UseSpringSecurityinThymeleafescapedexpressionsinJavaScript【发布时间】:2017-05-1623:56:26【问题描述】:Thymeleaf3.0可以做到这一点:/*[#th:if="$user.admin"]*/alert(\'Welcomeadmin\');/*[/]*... 查看详情

ENUM 验证 spring 表达式语言

】ENUM验证spring表达式语言【英文标题】:ENUMvalidationspringexpressionlanguage【发布时间】:2015-06-1408:32:33【问题描述】:我正在尝试验证一个内部映射到ENUMbusinessType内部服务的json字段。我无法在SpEL中编写逻辑来断言business_typejson字... 查看详情