5.4.1 xml风格的配置
SpEL支持在Bean定义时注入,默认使用“#{SpEL表达式}”表示,其中“#root”根对象默认可以认为是ApplicationContext,只有ApplicationContext实现默认支持SpEL,获取根对象属性其实是获取容器中的Bean。
首先看下配置方式(chapter5/el1.xml)吧:
java代码:
-
<beanid="world"class="java.lang.String">
-
<constructor-argvalue="#{'World!'}"/>
-
</bean>
-
<beanid="hello1"class="java.lang.String">
-
<constructor-argvalue="#{'Hello'}#{world}"/>
-
</bean>
-
<beanid="hello2"class="java.lang.String">
-
<constructor-argvalue="#{'Hello'+world}"/>
-
<!--不支持嵌套的-->
-
<!--<constructor-argvalue="#{'Hello'#{world}}"/>-->
-
</bean>
-
<beanid="hello3"class="java.lang.String">
-
<constructor-argvalue="#{'Hello'+@world}"/>
-
</bean>
模板默认以前缀“#{”开头,以后缀“}”结尾,且不允许嵌套,如“#{'Hello'#{world}}”错误,如“#{'Hello' + world}”中“world”默认解析为Bean。当然可以使用“@bean”引用了。
接下来测试一下吧:
java代码:
-
@Test
-
publicvoidtestXmlExpression(){
-
ApplicationContextctx=newClassPathXmlApplicationContext("chapter5/el1.xml");
-
Stringhello1=ctx.getBean("hello1",String.class);
-
Stringhello2=ctx.getBean("hello2",String.class);
-
Stringhello3=ctx.getBean("hello3",String.class);
-
Assert.assertEquals("HelloWorld!",hello1);
-
Assert.assertEquals("HelloWorld!",hello2);
-
Assert.assertEquals("HelloWorld!",hello3);
-
}
是不是很简单,除了XML配置方式,Spring还提供一种注解方式@Value,接着往下看吧。
5.4.2 注解风格的配置
基于注解风格的SpEL配置也非常简单,使用@Value注解来指定SpEL表达式,该注解可以放到字段、方法及方法参数上。
测试Bean类如下,使用@Value来指定SpEL表达式:
java代码:
-
packagecn.javass.spring.chapter5;
-
importorg.springframework.beans.factory.annotation.Value;
-
publicclassSpELBean{
-
@Value("#{'Hello'+world}")
-
privateStringvalue;
-
-
}
首先看下配置文件(chapter5/el2.xml):
java代码:
-
<?xmlversion="1.0"encoding="UTF-8"?>
-
<beansxmlns="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:
-
http:
-
http:
-
http:
-
<context:annotation-config/>
-
<beanid="world"class="java.lang.String">
-
<constructor-argvalue="#{'World!'}"/>
-
</bean>
-
<beanid="helloBean1"class="cn.javass.spring.chapter5.SpELBean"/>
-
<beanid="helloBean2"class="cn.javass.spring.chapter5.SpELBean">
-
<propertyname="value"value="haha"/>
-
</bean>
-
</beans>
配置时必须使用“<context:annotation-config/>”来开启对注解的支持。
有了配置文件那开始测试吧:
java代码:
-
@Test
-
publicvoidtestAnnotationExpression(){
-
ApplicationContextctx=newClassPathXmlApplicationContext("chapter5/el2.xml");
-
SpELBeanhelloBean1=ctx.getBean("helloBean1",SpELBean.class);
-
Assert.assertEquals("HelloWorld!",helloBean1.getValue());
-
SpELBeanhelloBean2=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前缀及后缀修改掉是安全的,具体代码如下:
java代码:
-
packagecn.javass.spring.chapter5;
-
importorg.springframework.beans.BeansException;
-
importorg.springframework.beans.factory.config.BeanFactoryPostProcessor;
-
importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-
importorg.springframework.context.expression.StandardBeanExpressionResolver;
-
publicclassSpELBeanFactoryPostProcessorimplementsBeanFactoryPostProcessor{
-
@Override
-
publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)
-
throwsBeansException{
-
StandardBeanExpressionResolverresolver=(StandardBeanExpressionResolver)beanFactory.getBeanExpressionResolver();
-
resolver.setExpressionPrefix("%{");
-
resolver.setExpressionSuffix("}");
-
}
-
}
首先通过 ConfigurableListableBeanFactory的getBeanExpressionResolver方法获取BeanExpressionResolver实现,其次强制类型转换为StandardBeanExpressionResolver,其为Spring默认实现,然后改掉前缀及后缀。
开始测试吧,首先准备配置文件(chapter5/el3.xml):
java代码:
-
<?xmlversion="1.0"encoding="UTF-8"?>
-
<beansxmlns="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:
-
http:
-
http:
-
http:
-
<context:annotation-config/>
-
<beanclass="cn.javass.spring.chapter5.SpELBeanFactoryPostProcessor"/>
-
<beanid="world"class="java.lang.String">
-
<constructor-argvalue="%{'World!'}"/>
-
</bean>
-
<beanid="helloBean1"class="cn.javass.spring.chapter5.SpELBean"/>
-
<beanid="helloBean2"class="cn.javass.spring.chapter5.SpELBean">
-
<propertyname="value"value="%{'Hello'+world}"/>
-
</bean>
-
</beans>
配置文件和注解风格的几乎一样,只有SpEL表达式前缀变为“%{”了,并且注册了“cn.javass.spring.chapter5.SpELBeanFactoryPostProcessor”Bean,用于修改前缀和后缀的。
写测试代码测试一下吧:
java代码:
-
@Test
-
publicvoidtestPrefixExpression(){
-
ApplicationContextctx=newClassPathXmlApplicationContext("chapter5/el3.xml");
-
SpELBeanhelloBean1=ctx.getBean("helloBean1",SpELBean.class);
-
Assert.assertEquals("#{'Hello'+world}",helloBean1.getValue());
-
SpELBeanhelloBean2=ctx.getBean("helloBean2",SpELBean.class);
-
Assert.assertEquals("HelloWorld!",helloBean2.getValue());
-
}
此处helloBean1 中通过@Value注入的“#{'Hello' + world}”结果还是“#{'Hello' + world}”说明不对其进行SpEL表达式求值了,而helloBean2使用“%{'Hello' + world}”注入,得到正确的“"Hello World!”。
分享到:
相关推荐
【第五章】Spring表达式语言 之 5.4在Bean定义中使用EL—跟我学spring3 【第六章】 AOP 之 6.1 AOP基础 ——跟我学spring3 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我学spring3 【第六章】 AOP 之 6.3 基于...
Spring Expression Language (SpEL)中文文档。基于Spring4.x。
1.17 【第五章】Spring表达式语言 之 5.4在Bean定义中使用EL—跟我学spring3 . . . . . . . . . . . . . . . .197 1.18 【第六章】 AOP 之 6.1 AOP基础 ——跟我学spring3 . . . . . . . . . . . . . . . . . . . ....
spring 表达式
—— 5.1 概述 5.2 SpEL基础5.3 SpEL语法5.4在Bean定义中使用EL6.1 AOP基础6.2 AOP的HelloWorld6.3 基于Schema的AOP6.4 基于@AspectJ的AOP 6.5 AspectJ切入点语法详解6.6 通知参数6.7 通知顺序6.8 切面实例化模型
【第十二章】零配置 之 12.4 基于Java类定义Bean配置元数据 ——跟我学spring3 【第十二章】零配置 之 12.5 综合示例-积分商城 ——跟我学spring3 【第十三章】 测试 之 13.1 概述 13.2 单元测试 ——跟我学spring3 ...
Spring 中文开发手册 spring中文API Spring_表达式语言 Spring+3+中文参考手册
spring3.0.2的api文档以及spring表达式语言
spring2.5向spring3过渡,必学零配置注解实现Bean定义。
本篇文章主要介绍了Spring 中如何控制2个bean中的初始化顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
spring动态向容器中添加bean和删除指定bean,不需要重启应用
EL表达式 (详解) EL表达式 1、EL简介 1)语法结构 ${expression} 2)[]与.运算符 EL 提供.和[]两种运算符来存取数据。 当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 ...
主要介绍了Spring实战之Bean定义中的SpEL表达式语言支持操作,结合实例形式分析了Bean定义中的SpEL表达式语言操作步骤与实现技巧,需要的朋友可以参考下
spring运行过程中动态注册bean,代码实例
在非spring注解类中使用spring容器中的bean_普通类中使用yml配置文件中的配置信息,在大数据采集项目中用到的,已经测试过了
NULL 博文链接:https://conkeyn.iteye.com/blog/2354644
跟我学spring3 跟我学spring3 跟我学spring3
11.2 实现通用层 11.3 实现积分商城层 12.1 概述 12.2 注解实现Bean依赖注入 12.3 注解实现Bean定义 12.4 基于Java类定义Bean配置元数据 12.5 综合示例-积分商城 13.1 概述 13.2 单元测试 集成测试 ——跟我学spring3