开涛spring3(5.4) - Spring表达式语言 之 5.4在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(5.4) - Spring表达式语言 之 5.4在Bean定义中使用EL的更多相关文章
- Spring表达式语言 之 5.4在Bean定义中使用EL(拾伍)
5.4.1 xml风格的配置 SpEL支持在Bean定义时注入,默认使用"#{SpEL表达式}"表示,其中"#root"根对象默认可以认为是Applicati ...
- 开涛spring3(5.3) - Spring表达式语言 之 5.3 SpEL语法
5.3 SpEL语法 5.3.1 基本表达式 一.字面量表达式: SpEL支持的字面量包括:字符串.数字类型(int.long.float.double).布尔类型.null类型. 类型 示例 字 ...
- 开涛spring3(12.3) - 零配置 之 12.3 注解实现Bean定义
12.3 注解实现Bean定义 12.3.1 概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[12.2注解实现Bean依赖注入]一节中介绍了通过注解来减少配置数量,但并没有完全 ...
- 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入
12.2 注解实现Bean依赖注入 12.2.1 概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的 ...
- Spring3系列6 - Spring 表达式语言(Spring EL)
Spring3系列6-Spring 表达式语言(Spring EL) 本篇讲述了Spring Expression Language —— 即Spring3中功能丰富强大的表达式语言,简称SpEL.S ...
- 开涛spring3(12.4) - 零配置 之 12.4 基于Java类定义Bean配置元数据
12.4 基于Java类定义Bean配置元数据 12.4.1 概述 基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件. 基于Java ...
- 开涛spring3(9.4) - Spring的事务 之 9.4 声明式事务
9.4 声明式事务 9.4.1 声明式事务概述 从上节编程式实现事务管理可以深刻体会到编程式事务的痛苦,即使通过代理配置方式也是不小的工作量. 本节将介绍声明式事务支持,使用该方式后最大的获益是简 ...
- 开涛spring3(9.2) - Spring的事务 之 9.2 数据库事务概述
9.2.1 概述 Spring框架支持事务管理的核心是事务管理器抽象,对于不同的数据访问框架(如Hibernate)通过实现策略接口 PlatformTransactionManager,从而能支持 ...
- 开涛spring3(9.3) - Spring的事务 之 9.3 编程式事务
9.3 编程式事务 9.3.1 编程式事务概述 所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理. Spring框架提供一致的事务抽象,因此对于JDBC还是JTA事务都是 ...
随机推荐
- C#遍历指定文件夹中的所有文件(转)
原文链接:http://www.cnblogs.com/qianqianfy/archive/2009/07/08/1518974.html 1. C#遍历指定文件夹中的所有文件 DirectoryI ...
- javascript中的几种遍历方法浅析
1. for...in 用于对数组或者对象的属性的可枚举属性进行循环操作.注意该对象来自原型链上的可枚举属性也会被循环.下面看例子 var arr = ["lee","h ...
- 易汇金在线支付接口实例。ecshop和shopex,shopnc,iwebshop下完美无错(最新)
最近为客户的一个在线商城做了一个易汇金在线支付的接口.跟大家分享一下. 1 首先可以模仿其他的接口,比如支付宝,财付通等的接口,构建模块功能文件和语言文件. 功能模块构建: /includes/mod ...
- 使用HttpClient进行Get方式通信
下载apache包 http://hc.apache.org/downloads.cgi 比较eclipse自带api,简单,易上手 实例: package zw1; import java.io.I ...
- 通过web对.exe程序进行更新和修改
实现功能:通过网站更新用户的软件,需要联网,也可以通过本地网站更新局域网用户软件. 根本实现:1.一个网站(我用的是自己的www.aq36.xyz ,本地就可以,可以用localhost)然后运行up ...
- 【转载】google搜索从入门到精通
原文地址:http://www.cnblogs.com/helloIT/articles/5095668.html /***************************************** ...
- [ext4]01 磁盘布局 - block分析
ext4文件系统最基本的分配单元是"block"(块). block是由一组连续的sectors来组成,其大小介于1k~4K之间,当然不可能是任意值,只能是2的整数次幂个secto ...
- Roguelike元素对游戏设计的影响
Roguelike game自1980年以来,就占据着游戏市场中很大的份额,而现如今的很多游戏中,也加入了Roguelike元素来起到更好的效果.我们知道Roguelike game中有着一些看似任性 ...
- JS上了贼船
本文纯属个人观点,没有引经据典,没有小心求证,just吐槽. 互联网的火热.移动web,带动了前端的飞速发展,js好像搭上了顺风车,身价水涨船高,如日中天. web前端是啥?html + css + ...
- 小米红米1 android 4.4.4上操作数据库异常问题
产生的问题: 小米红米1 android 4.4.4上,按HOME键,应用进入后台,再启动,应用进程直接挂掉 解决的方法: 这个是操作数据库,数据库关闭之后导致的异常,解决的方法: //4.0以上的版 ...