spring之SpEL表达式详解

目录
  • 1.什么是SpEL表达式
  • 2.SpEL表达式语言入门程序
    • (1)xml配置的方式
    • (2)采用注解的方式
  • 3.分析器
  • 4.使用SpEL表达式调用方法
    • (1)使用SpEL调用普通方法
    • (2)使用SpEL调用构造方法
    • (3)使用SpEL调用静态方法
  • 6.使用SpEL表达式调用变量和函数
    • (1)#变量的表达式使用
    • (2)#root表达式的使用
    • (3)访问系统的属性和环境
  • 7.使用SpEL表达式中的运算符

1.什么是SpEL表达式

SpEL表达式语言是一种表达式语言,是一种可以与一个基于spring的应用程序中的运行时对象交互的东西。有点类似于ognl表达式。总得来说SpEL表达式是一种简化开发的表达式,通过使用表达式来简化开发,减少一些逻辑、配置的编写。

2.SpEL表达式语言入门程序

(1)xml配置的方式

配置环境:pom.xml

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
</dependencies>

applicationContext.xml文件:

<bean id="MyMessage" class="cn.spy.spel.injection.MyMessage">
        <property name="message" value="#{systemProperties['user.language']}"></property>
</bean>

MyMessage.java文件:

public class MyMessage {

	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

}

测试程序:

public class Test {
	public static void main(String[] args) {
		ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
		MyMessage myMessage =context.getBean(MyMessage.class);
		System.out.println(myMessage.getMessage());
	}
}

结果:

解释:这里使用了表达式#{systemProperties['user.language']}来设置值,用来检索用户语言系统的属性。

(2)采用注解的方式

applicationContext.xml文件:

<context:component-scan base-package="cn.spy.spel"></context:component-scan>

MyMessage2.java文件:

@Component
public class MyMessage2 {

	@Value("#{systemProperties['user.language']}")
	private String message;

	public String getMessage() {
		return message;
	}
}

解释:这里使用了@Value注解的方式,当实例化MyMessage2这个bean的时候,将使用该注解设置默认值。此处还是使用了之前的SpEL表达式,来设置用户语言系统的属性。(在这里@Value注解既可以在类的字段属性上面,也可以在构造函数和方法上面使用)。

测试:

public static void main(String[] args) {
		ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
		MyMessage2 myMessage =context.getBean(MyMessage2.class);
		System.out.println(myMessage.getMessage());
	}

结果:

3.分析器

SpEL上下文中所定义的每一个表达式都应该首先被解析,然后在被评估。解析的过程采用了ExpressionParser接口的分析器进行处理的。SpelExpressionParser主要负责将字符串表达式解析到已编译的Expression对象中。(创建的分析器实例是线程安全)

代码形式:

ExpressionParser parser =new SpelExpressionParser();

注意:

在SpEL表达式中,默认情况下,表达式前缀为 ' # ' ,而后缀为 ' } ' 。如果表达式中没有前缀和后缀,那么表达式字符串就被当作纯文本。

分析器解析Spel中纯文本表达式HelloWorld:

public class HelloWorldTest {
	ExpressionParser parser;

	@Before
	public void setup(){
		//初始化创建SpEL表达式解析器
		parser =new SpelExpressionParser();
	}

	@Test
	public void test(){
		//使用解析器解析出表达式exp
		Expression exp=parser.parseExpression("'Hello World'");
		//在表达式中获取指定类型的值
		String value =exp.getValue(String.class);
		assertThat(value ,is("Hello World"));
	}
}

junit测试结果:

4.使用SpEL表达式调用方法

(1)使用SpEL调用普通方法

就是SpEL也支持在表达式中采用方法调用的形式

范例:

User.java:

public class User {

	private String username;
	private String password;
	public void setUsername(String username) {
		this.username = username;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getUsername() {
		return "李四";
	}
	public String getPassword() {
		return "lisi123";
	}
	public void printUser(){
		System.out.println("当前用户的用户名:"+username+" ,密码:"+password);
	}
}

applicationContext.xml配置文件:

        <bean id="user1" class="cn.spy.spel.method.User">
			<property name="username" value="张三"></property>
			<property name="password" value="zhangsan123"></property>
		</bean>		

		<bean id="user2" class="cn.spy.spel.method.User">
			<property name="username" value="#{user2.getUsername()}"></property>
			<property name="password" value="#{user2.getPassword()}"></property>
		</bean>	

测试:

public class TestMethod {
	public static void main(String[] args) {
		ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
		User user1 =(User) context.getBean("user1");
		user1.printUser();
		User user2 =(User) context.getBean("user2");
		user2.printUser();
	}
}

结果:

(2)使用SpEL调用构造方法

@Test
public void test(){
	ExpressionParser parser =new SpelExpressionParser();
	Expression exp=parser.parseExpression("new Double(3.1415926)");
	Double value =exp.getValue(Double.class);
	assertThat(value ,is(3.1415926));
}

结果:

(3)使用SpEL调用静态方法

@Test
public void test(){
	ExpressionParser parser =new SpelExpressionParser();
	Expression exp=parser.parseExpression("T(java.lang.Math).abs(-1)");
	Integer value =exp.getValue(Integer.class);
	assertThat(value ,is(1));
}

结果:

6.使用SpEL表达式调用变量和函数

(1)#变量的表达式使用

SpEL使用上下文StandardEvaluationContext查找表达式中存在的变量。在表达式中使用变量名称前添加一个标签前缀#,使用已注册的变量。

public class TestSpEL {
	@Test
	public void test(){
		ExpressionParser parser =new SpelExpressionParser();
		StandardEvaluationContext context =new StandardEvaluationContext();
		context.setVariable("message", "Hello World");
		String value =parser.parseExpression("#message").getValue(context, String.class);
		assertThat(value, is("Hello World"));
	}
}

结果:

(2)#root表达式的使用

可以在上下文中设置一个对象评估,可以使用#root访问该对象。

public class TestSpEL {
	@Test
	public void test(){
		ExpressionParser parser =new SpelExpressionParser();
		StandardEvaluationContext context =new StandardEvaluationContext();
		context.setRootObject(new Var());
		Assert.assertTrue(parser.parseExpression("#root").getValue(context) instanceof Var);
	}
}

结果:

(3)访问系统的属性和环境

SpEL预定义变量:systemProperties和systemEnvironment

parser.parseExpression("@systemProperties['java.version']").getValue(context);
parser.parseExpression("@systemProperties[JAVA_HOME]").getValue(context);

7.使用SpEL表达式中的运算符

SpEL提供了多种运算符。


类型


运算符


关系


<,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne


算术


+,- ,* ,/,%,^


逻辑


&&,||,!,and,or,not,between,instanceof


条件


?: (ternary),?: (elvis)


正则表达式


matches


其他类型


?.,?[…],![…],^[…],$[…]

注意:如果解析表达式时,在完全限定的类名中包含一个运算符的文本表示形式,则会产生异常。

正则表达式运算符matches

@Test
	public void test(){
		ExpressionParser parser =new SpelExpressionParser();
		assertThat(parser.parseExpression("35 matches '[0-9]+'").getValue(Boolean.class), is(true));
	}

结果:

逻辑运算符between

@Test
public void test(){
	ExpressionParser parser =new SpelExpressionParser();
	assertThat(parser.parseExpression("3 between {2,5}").getValue(Boolean.class), is(true));
}

结果:

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 基于spring @Cacheable 注解的spel表达式解析执行逻辑

    目录 直接进入主题 跟随spring的调用链 直接看 @Cacheable 注解就可以了 接下来看 key获取是在哪里 没有任何逻辑就是一个组装 了解一下@Cacheable的拦截顺序 接下来看 execute方法 再看 重载方法execute 日常使用中spring的 @Cacheable 大家一定不陌生,基于aop机制的缓存实现,并且可以选择cacheManager具体提供缓存的中间件或者进程内缓存,类似于 @Transactional 的transactionManager ,都是提供了一

  • Spring表达式语言SpEL用法详解

    这篇文章主要介绍了spring表达式语言SpEL用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 (1)spring表达式语言是一个支持运行时查询和操作对象图得我强大表达式语言. (2)语言类似于EL:SpEL使用#{...}作为定界符.所有在大括号中的字符串均被认为是SpEL. (3)SpEL为bean的属性进行动态赋值提供了便利. (4)通过SpEL可以实现: 通过Bean的id对Bean进行引用 调用方法及引用对象的属性 计算表达式

  • 使用Springboot自定义注解,支持SPEL表达式

    目录 Springboot自定义注解,支持SPEL表达式 1.自定义注解 2.使用AOP拦截方法,解析注解参数 自定义注解结合切面和spel表达式 自定义一个注解 自定义一个service类,在需要拦截的方法上加上@Log注解 写一个自定义切面 pom文件的依赖 测试 增加内容 Springboot自定义注解,支持SPEL表达式 举例,自定义redis模糊删除注解 1.自定义注解 import java.lang.annotation.ElementType; import java.lang.

  • Spring Cache抽象-使用SpEL表达式解析

    目录 Spring Cache抽象-使用SpEL表达式 概述 SpEl表达式 如何让自定义注解支持SpEL表达式 使用方法 使用案例 1.准备 2.自定义注解 3.定义AOP拦截注解对方法增强进行读写缓存 4.测试 Spring Cache抽象-使用SpEL表达式 概述 在Spring Cache注解属性中(比如key,condition和unless),Spring的缓存抽象使用了SpEl表达式,从而提供了属性值的动态生成及足够的灵活性. 下面的代码根据用户的userCode进行缓存,对于ke

  • Spring实战之Bean定义中的SpEL表达式语言支持操作示例

    本文实例讲述了Spring实战之Bean定义中的SpEL表达式语言支持操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <!-- 指定Spring配置文件的根元素和Schema 导入p:命名空间和util:命名空间的元素 --> <beans xmlns="http://www.springframework.org/schema/beans"

  • Spring组件开发模式支持SPEL表达式

    本文是一个 Spring 扩展支持 SPEL 的简单模式,方便第三方通过 Spring 提供额外功能. 简化版方式 这种方式可以在任何能获取ApplicationContext 的地方使用.还可以提取一个方法处理动态 SPEL 表达式. import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.beans.

  • Spring spel表达式使用方法示例

    spring in action第三版读书笔记 spring3.0引入了spring expression language(spel)语言,通过spel我们可以实现 1.通过bean的id对bean进行引用 2.调用方法以及引用对象中的属性 3.计算表达式的值 4.正则表达式的匹配 5.集合的操作 spel最终的目标是得到表达式计算之后的值,这些表达式可能是列举的一些值,引用对象的某些属性,或者是类中的某些常量,复杂的spel表达式通常都是由一些简单的元素构成的.最简单的仅仅是得到一些给出元素

  • spring之SpEL表达式详解

    目录 1.什么是SpEL表达式 2.SpEL表达式语言入门程序 (1)xml配置的方式 (2)采用注解的方式 3.分析器 4.使用SpEL表达式调用方法 (1)使用SpEL调用普通方法 (2)使用SpEL调用构造方法 (3)使用SpEL调用静态方法 6.使用SpEL表达式调用变量和函数 (1)#变量的表达式使用 (2)#root表达式的使用 (3)访问系统的属性和环境 7.使用SpEL表达式中的运算符 1.什么是SpEL表达式 SpEL表达式语言是一种表达式语言,是一种可以与一个基于spring

  • Spring 缓存抽象示例详解

    Spring缓存抽象概述 Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成. Cache接口为缓存的组件规范定义,包含缓存的各种操作集合: Cache接口下Spring提供了各种xxxCache的实现:如RedisCache,EhCacheCache , ConcurrentMapCa

  • 基于springEL表达式详解及应用

    目录 基于springEL表达式详解及应用 什么是SpringEL? 为什么要使用SpringEL? 如何使用SpringEL? 使用SpringEL注入简单值 使用SpringEL调用方法 SpringEL调用静态类或常量 SpringEL运算 SpringEL使用正则表达式 SpringEL操作集合 Spring操作外部Properties文件 SpringEL查询筛选集合和投影 优点: 缺点: 笔者实际应用: 总结: 基于springEL表达式详解及应用 什么是SpringEL? Spri

  • Spring AOP 基于注解详解及实例代码

    Spring AOP  基于注解详解及实例代码 1.启用spring对@AspectJ注解的支持: <beans xmlns:aop="http://www.springframework.org/schema/aop"...> <!--启动支持--> <aop:aspectj-autoproxy /> </beans> 也可以配置AnnotationAwareAspectJAutoProxyCreator Bean来启动Spring对@

  • Spring AOP  基于注解详解及实例代码

    Spring AOP  基于注解详解及实例代码 1.启用spring对@AspectJ注解的支持: <beans xmlns:aop="http://www.springframework.org/schema/aop"...> <!--启动支持--> <aop:aspectj-autoproxy /> </beans> 也可以配置AnnotationAwareAspectJAutoProxyCreator Bean来启动Spring对@

  • Spring Boot整合Thymeleaf详解

    目录 Thymeleaf 基本介绍 基本语法 th:text文本替换 th:if和th:unless文本替换 th:each foreach循环 th:id.th:value.th:checked等(和form表单相关) 整合Thymeleaf 基本配置 三层架构 删除操作 编辑操作 用户登录 用户注销 点击注销用户 Thymeleaf 基本介绍 Spring Boot 官方推荐使用 Thymeleaf 作为其模板引擎.SpringBoot 为 Thymeleaf 提供了一系列默认配置,并且为T

  • JSP 中Spring Bean 的作用域详解

    JSP 中Spring Bean 的作用域详解 Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1>singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例.一般Spring容器默认Bean的作用域为singleton 2>prototype: 与singleton相反, 每次通过容器的getBean()方法获取该作用域下的Bean时都将产生一个新的Bean实例 3>request: 对于同一次Http

  • java中Spring Security的实例详解

    java中Spring Security的实例详解 spring security是一个多方面的安全认证框架,提供了基于JavaEE规范的完整的安全认证解决方案.并且可以很好与目前主流的认证框架(如CAS,中央授权系统)集成.使用spring security的初衷是解决不同用户登录不同应用程序的权限问题,说到权限包括两部分:认证和授权.认证是告诉系统你是谁,授权是指知道你是谁后是否有权限访问系统(授权后一般会在服务端创建一个token,之后用这个token进行后续行为的交互). spring

  • Spring Java-based容器配置详解

    装Java-based的配置 使用 @Import 注解 跟在Spring XML文件中使用<import>元素添加模块化的配置类似,@Import注解允许你加载其他配置类中的@Bean定义: @Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public

随机推荐