文档章节

Spring表达式语言:SpEL(三)

heroShane
 heroShane
发布于 2014/02/02 18:24
字数 1034
阅读 182
收藏 1

本文为转载学习

原文链接:http://jinnianshilongnian.iteye.com/blog/1418311

5.4.1  xml风格的配置


       SpEL支持在Bean定义时注入,默认使用“#{SpEL表达式}”表示,其中“#root”根对象默认可以认为是ApplicationContext,只有ApplicationContext实现默认支持SpEL,获取根对象属性其实是获取容器中的Bean。

       首先看下配置方式(chapter5/el1.xml)吧:

<bean id="world" class="java.lang.String">  
    <constructor-arg value="#{' World!'}"/>  
</bean>  
<bean id="hello1" class="java.lang.String">  
    <constructor-arg value="#{'Hello'}#{world}"/>  
</bean>    
<bean id="hello2" class="java.lang.String">  
    <constructor-arg value="#{'Hello' + world}"/>  
    <!-- 不支持嵌套的 -->  
    <!--<constructor-arg value="#{'Hello'#{world}}"/>-->  
</bean>  
<bean id="hello3" class="java.lang.String">  
    <constructor-arg value="#{'Hello' + @world}"/>  
</bean>

模板默认以前缀“#{”开头,以后缀“}”结尾,且不允许嵌套,如“#{'Hello'#{world}}”错误,如“#{'Hello' + world}”中“world”默认解析为Bean。当然可以使用“@bean”引用了。

 

       接下来测试一下吧:

@Test  
public void testXmlExpression() {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter5/el1.xml");  
    String hello1 = ctx.getBean("hello1", String.class);  
    String hello2 = ctx.getBean("hello2", String.class);  
    String hello3 = ctx.getBean("hello3", String.class);  
    Assert.assertEquals("Hello World!", hello1);  
    Assert.assertEquals("Hello World!", hello2);  
    Assert.assertEquals("Hello World!", hello3);  
}

是不是很简单,除了XML配置方式,Spring还提供一种注解方式@Value ,接着往下看吧。

 

5.4.2  注解风格的配置


       基于注解风格的SpEL配置也非常简单,使用@Value注解来指定SpEL表达式,该注解可以放到字段、方法及方法参数上。

       测试Bean类如下,使用@Value来指定SpEL表达式:

package cn.javass.spring.chapter5;  
import org.springframework.beans.factory.annotation.Value;  
public class SpELBean {  
    @Value("#{'Hello' + world}")  
    private String value;  
    //setter和getter由于篇幅省略,自己写上  
}

首先看下配置文件(chapter5/el2.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"  
        xmlns:context="http://www.springframework.org/schema/context"  
        xsi:schemaLocation="  
          http://www.springframework.org/schema/beans  
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
          http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
   <context:annotation-config/>  
   <bean id="world" class="java.lang.String">  
       <constructor-arg value="#{' World!'}"/>  
   </bean>  
   <bean id="helloBean1" class="cn.javass.spring.chapter5.SpELBean"/>  
   <bean id="helloBean2" class="cn.javass.spring.chapter5.SpELBean">  
       <property name="value" value="haha"/>  
   </bean>  
</beans>

配置时必须使用“<context:annotation-config/>”来开启对注解的支持。

 

       有了配置文件那开始测试吧:

@Test  
public void testAnnotationExpression() {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter5/el2.xml");  
    SpELBean helloBean1 = ctx.getBean("helloBean1", SpELBean.class);  
    Assert.assertEquals("Hello World!", helloBean1.getValue());  
    SpELBean helloBean2 = ctx.getBean("helloBean2", SpELBean.class);  
    Assert.assertEquals("haha", helloBean2.getValue());  
}

其中“helloBean1 ”值是SpEL表达式的值,而“helloBean2”是通过setter注入的值,这说明setter注入将覆盖@Value的值。

5.4.3  在Bean定义中SpEL的问题


       如果有同学问“#{我不是SpEL表达式}”不是SpEL表达式,而是公司内部的模板,想换个前缀和后缀该如何实现呢?

       那我们来看下Spring如何在IoC容器内使用BeanExpressionResolver接口实现来求值SpEL表达式,那如果我们通过某种方式获取该接口实现,然后把前缀后缀修改了不就可以了。

       此处我们使用BeanFactoryPostProcessor接口提供postProcessBeanFactory回调方法,它是在IoC容器创建好但还未进行任何Bean初始化时被ApplicationContext实现调用,因此在这个阶段把SpEL前缀及后缀修改掉是安全的,具体代码如下:

package cn.javass.spring.chapter5;  
import org.springframework.beans.BeansException;  
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;  
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;  
import org.springframework.context.expression.StandardBeanExpressionResolver;  
public class SpELBeanFactoryPostProcessor implements BeanFactoryPostProcessor {  
    @Override  
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)  
        throws BeansException {  
        StandardBeanExpressionResolver resolver = (StandardBeanExpressionResolver) beanFactory.getBeanExpressionResolver();  
        resolver.setExpressionPrefix("%{");  
        resolver.setExpressionSuffix("}");  
    }  
}

首先通过 ConfigurableListableBeanFactory的getBeanExpressionResolver方法获取BeanExpressionResolver实现,其次强制类型转换为StandardBeanExpressionResolver,其为Spring默认实现,然后改掉前缀及后缀。

开始测试吧,首先准备配置文件(chapter5/el3.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"  
        xmlns:context="http://www.springframework.org/schema/context"  
        xsi:schemaLocation="  
           http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
   <context:annotation-config/>  
   <bean class="cn.javass.spring.chapter5.SpELBeanFactoryPostProcessor"/>  
   <bean id="world" class="java.lang.String">  
       <constructor-arg value="%{' World!'}"/>  
   </bean>  
   <bean id="helloBean1" class="cn.javass.spring.chapter5.SpELBean"/>  
   <bean id="helloBean2" class="cn.javass.spring.chapter5.SpELBean">  
       <property name="value" value="%{'Hello' + world}"/>  
   </bean>  
</beans>

配置文件和注解风格的几乎一样,只有SpEL表达式前缀变为“%{”了,并且注册了“cn.javass.spring.chapter5.SpELBeanFactoryPostProcessor”Bean,用于修改前缀和后缀的。

       写测试代码测试一下吧:

@Test  
public void testPrefixExpression() {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter5/el3.xml");  
    SpELBean helloBean1 = ctx.getBean("helloBean1", SpELBean.class);  
    Assert.assertEquals("#{'Hello' + world}", helloBean1.getValue());  
    SpELBean helloBean2 = ctx.getBean("helloBean2", SpELBean.class);  
    Assert.assertEquals("Hello World!", helloBean2.getValue());  
}

此处helloBean1 中通过@Value注入的“#{'Hello' + world}”结果还是“#{'Hello' + world}”说明不对其进行SpEL表达式求值了,而helloBean2使用“%{'Hello' + world}”注入,得到正确的“"Hello World!”。


本文转载自:http://jinnianshilongnian.iteye.com/blog/1418311

heroShane
粉丝 117
博文 229
码字总数 9508
作品 0
广州
私信 提问
Spring Bean定义中表达式语言的支持

SpEL(Spring Expression Language,Spring表达式语言)的一个重要的作用就是扩展Spring容器的功能,允许在Bean定义中使用SpEL。XML配置文件和Annotation中都可以使用SpEL。在XML和Annotatio...

摆渡者
2014/03/09
0
0
《Spring5学习》 03 运行时值注入

Spring的运行时值注入是为了在一些应用场景避免将属性值硬编码在配置类中而提供的解决方案,Spring目前提供了几种方式实现运行时值注入,下面我们分别来讲下 1 - Spring中的Environment 在S...

老韭菜
2018/08/14
0
0
说说 Spring 表达式语言(SpEL)的核心类与用法

Spring 表达式语言 Spring Expression Language(简称 SpEL )是一个支持运行时查询和操作对象图的表达式语言 。 语法类似于 EL 表达式 ,但提供了显式方法调用和基本字符串模板函数等额外特...

deniro
2018/09/08
0
0
Spring Expression Language(SpEL) spring表达式语言

10.Spring Expression Language(SpEL) spring表达式语言 10.1 介绍 SPEL语言是一个非常强力的支持运行时查询和操作对象图谱的语言.这个语言语法和传统EL表达式相似,但提供了许多额外功能,最重...

流光韶逝
2016/11/02
0
0
Spring3表达式语言(SpEL)的预定义变量

spring3 SpEL 的两个内置变量在xml里的用法: <bean id="xxx" value="#{systemProperties['java.io.tmpdir']}"><bean> systemProperties主要是在vm启动时通过-D设置的系统属性 <bean id="xx......

伊森papa
2012/04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

solr实例

需求:使用Solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序,并且实现分页功能。 一.架构设计:1.solr服务器 2.自己开发的应用(2.1...

klmkom
29分钟前
0
0
在知乎上看到一个关于Python资源的很不错的主题,可惜点赞不过400多

看上去,混知乎的技术相关的人还是少。 哪些 Python 库让你相见恨晚? Lingfeng Ai,伯乐在线技术翻译组,欢迎喜欢互联网和英… bulan1989、五德 等人赞同 Awesome Python中文版来啦! 本文由...

dillonxiao
35分钟前
1
0
Django编写数据模型类

设计数据库和表结构是做网站的基础。在Django中,不需要通过SQL语句直接跟数据库打交道,而是完全用Python的类来创建数据模型,之后交给Django完成创建数据库的操作。 数据模型类 数据模型类...

ZeroBit
38分钟前
1
0
关于TensorFlow 2.0,这里有你想知道的一切

全文共8094字,预计学习时长30分钟或更长 图片来源:pexels.com/@pixabay TensorFlow是谷歌2015年开源的通用高性能计算库。最初主要是为构建神经网络(NNs)提供高性能的API。然而,随着时间的...

读芯术
43分钟前
5
0
Wondershare Recoverit - 专业数据恢复神器,支持U盘、存储卡等外部设备!

Wondershare Recoverit 今天带来的这款软件叫做Wondershare Recoverit,是一款专业实用的数据恢复软件,也是一款比较久的数据恢复软件了,可以恢复所有文件类型。 包括照片、视频、文档和其他...

_Somuns
56分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部