Spring3: 在Bean定义中使用EL-表达式语言
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!”。
Spring3: 在Bean定义中使用EL-表达式语言的更多相关文章
- 开涛spring3(5.4) - Spring表达式语言 之 5.4在Bean定义中使用EL
5.4.1 xml风格的配置 SpEL支持在Bean定义时注入,默认使用“#{SpEL表达式}”表示,其中“#root”根对象默认可以认为是 ApplicationContext,只有Applica ...
- Spring表达式语言 之 5.4在Bean定义中使用EL(拾伍)
5.4.1 xml风格的配置 SpEL支持在Bean定义时注入,默认使用"#{SpEL表达式}"表示,其中"#root"根对象默认可以认为是Applicati ...
- JavaWeb -- Jsp中的 EL表达式
lEL 全名为Expression Language.EL主要作用: l获取数据: •EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数据.(某个web ...
- JSP中的EL 表达式
JSP中的EL 表达式 什么是 EL 表达式,EL 表达式的作用? EL 表达式的全称是:Expression Language.是表达式语言. EL 表达式的什么作用:EL 表达式主要是代替 jsp ...
- 怎样在js中使用EL表达式
相信已经有很多人对如何在js中使用EL表达式存有困惑,各种引号的处理不胜其烦. 1.在js(嵌入jsp页面)中通过定义变量的方式使用EL表达式: 如:var url = '${param.url}'; ...
- JS中使用EL表达式方法与获取工程名字
关键: 在js中使用el表达式一定要使用双引号 分两种情况 1. JS代码在JSP页面中, 这可以直接使用EL表达式. 如: <script type="text/javas ...
- js中“使用”el表达式
在说相关内容前,一定要先熟悉jsp运行原理: http://blog.csdn.net/lmsnju/article/details/4813488 http://hi.baidu.com/mingf ...
- JSP中使用EL表达式
EL表达式 :EL 全名为Expression Language,就是为了替代<%= %>脚本表达式. EL主要作用: 获取数据: EL表达式主要用于替换JSP页面中的脚本表达式,以从各种 ...
- js中使用EL表达式总结
1.js中使用el表达式要加双引号或单引号:'${list}' 2.js变量获取el表达式中的对象:不能直接获取,直接获取得到的是该对象的toString值. 有两种方法:一:el中直接写对象的属性v ...
随机推荐
- 转!!SpringMVC与Struts2区别与比较总结
1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上Spr ...
- 深入Redis内部-Redis 源码讲解(转)
Redis作为 NoSQL 数据库的杰出代表,一直广受关注,其轻量级的敏捷架构,向来有存储中的瑞士军刀之称.下面推荐的一篇文章,从源码的角度讲解了Redis 的整个工作流程,是了解 Redis 流程的 ...
- Django相关介绍
先认识一下MVC框架 MVC的框架模式,即模型M,视图V和控制器C.他们之间以一种插件似的,松耦合的方式连接在一起. Model(模型)是应用程序中用于处理应用程序数据逻辑的部分. 通常模型对象负责在 ...
- 安卓ios app自动化测试用例模板
import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidElem ...
- django【自定义分页】
1. views.py def app(request): page_info = PageInfo(request.GET.get('p'), 6, 100, request.path_info, ...
- mysql增量恢复的一个实例操作
通过防火墙禁止web等应用向主库写数据或者锁表,让主库暂时停止更新,然后进行恢复 模拟整个场景 1.登录数据库 [root@promote 3306]# mysql -uroot -S /data/3 ...
- 微信小程序组件swiper
视图容器swiper:官方文档 Demo Code Page({ data:{ imgUrls: [ 'http://img02.tooopen.com/images/20150928/tooopen ...
- linux crontab命令 自动下载文件
#crontab -e#download stock data, Mon-Fri, 9:15 - 11:30, 13:00 - 15:0015,30,40,50 9 * * 1-5 (cd /home ...
- Mac 一键显示所有隐藏文件 不要那么六好吧
系统应简洁而有效,对一般用户来说这一点尤为重要.不必要让普通用户知道的信息往往会给他们造成困扰,因而,隐藏掉他们便是个不错的选择,既可以保证系统平稳流畅运行,也可以为用户提供友好界面. 对于开发者而言 ...
- CF961G Partitions(第二类斯特林数)
题目 CF961G 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 相信大家能得出一个一眼式:\[Ans=\sum\limits_{i=1}^n w_i\sum\limi ...