Spring(23)——SPEL表达式(四)
来源:互联网 发布:惧内之滥觞乎 编辑:程序博客网 时间:2024/05/20 00:36
23.2.24 设置默认值
SpEl表达式中支持“a?:b”这样的语法来设置默认值。其表示如果a不为null时其结果为a,否则就为b。
@Testpublic void test24 () {ExpressionParser parser = new SpelExpressionParser();Assert.assertTrue(parser.parseExpression("#abc?:123").getValue().equals(123));//变量abc不存在Assert.assertTrue(parser.parseExpression("1?:123").getValue().equals(1));//数字1不为null}
23.2.25 安全导航
我们可能经常会使用类似于“a.b.c”这样的用法,表示a的b属性的c属性,但如果a为null或者a的b属性为null时都会出现空指针。为了避免此种情况发生,我们可以在SpEl表达式中使用安全导航,这样当a为null或a的b属性为null时将直接返回null,而不抛出空指针异常。SpEl表达式中安全导航的语法是将点“.”替换为“?.”,即不使用“a.b.c”,而是使用“a?.b?.c”。
@Testpublic void test25 () {ExpressionParser parser = new SpelExpressionParser();Assert.assertNull(parser.parseExpression("null?.abc").getValue());Assert.assertNull(parser.parseExpression("T(System)?.getProperty('abc')?.length()").getValue());//数字1不为null}
23.2.26 获取bean对象
在SpEL表达式里面也可以直接访问bean对象,前提是指定了一个BeanResolver。BeanResolver是一个接口,其只定义了一个方法resolve,用以通过beanName解析为对应的bean对象并返回,具体定义如下。
public interface BeanResolver {Object resolve(EvaluationContext context, String beanName) throws AccessException;}
如果要在SpEL表达式中访问bean对象,我们需要通过StandardEvaluationContext来设置对应的BeanResolver,同时我们需要在SpEL表达式中以“@beanName”的方式来访问对应的bean对象。如下是一段示例代码,我们在表达式中获取到了名称为hello的bean对象,并访问了其getKey()方法。
@Testpublic void test26() {ExpressionParser parser = new SpelExpressionParser();StandardEvaluationContext context = new StandardEvaluationContext();context.setBeanResolver(new MyBeanResolver());//访问bean名称为hello的bean对象的getKey()方法。Object obj = parser.parseExpression("@hello.key").getValue(context);System.out.println(obj);}private static class MyBeanResolver implements BeanResolver {private static ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");public Object resolve(EvaluationContext context, String beanName)throws AccessException {return appContext.getBean(beanName);}}
23.3 SpelParserConfiguration
在构建SpelExpressionParser时我们可以给其传递一个SpelParserConfiguration对象以对SpelExpressionParser进行配置。其可以用于指定在遇到List或Array为null时是否自动new一个对应的实例,对应SpelParserConfiguration的第一个构造参数;也可以指定在List或Array中对应索引超出了当前索引的最大值时是否自动进行扩充,对应SpelParserConfiguration的第二个构造参数,更多信息请参考Spring的API文档。如下示例中我们就使用了SpelParserConfiguration对象,指定了在对应的List或Array为null时自动new一个对应的对象,并且在对应的索引超出了List或Array当前的最大索引时自动对其进行扩充。所以如下示例中在我们第一次访问User的interests时其为null,之后第二次访问时,由于指定了将自动new对应的对象并且在索引超出时自动进行扩充,所以将new一个List的实例,对应ArrayList,且在索引5不存在时将自动扩充并进行填值,填值时将对List的元素类型String new 6次。所以对于这种情况我们需要保证List或Array中存放的元素类型存在无参构造方法。
class User {public List<String> interests;}@Testpublic void test() {User user = new User();SpelParserConfiguration parserConfig = new SpelParserConfiguration(true, true);ExpressionParser parser = new SpelExpressionParser(parserConfig);//第一次为nullAssert.assertNull(parser.parseExpression("interests").getValue(user));//自动new一个List的实例,对应ArrayList,并自动new String()添加6次。Assert.assertTrue(parser.parseExpression("interests[5]").getValue(user).equals(""));//size为6Assert.assertTrue(parser.parseExpression("interests.size()").getValue(user).equals(6));}
23.4 在bean定义中使用SpEl
在bean定义中使用SpEl表达式的语法是“#{exp}”。exp就是对应的表达式。如下示例中我们定义了一个名为hello的bean,在指定其userDir时我们使用了表达式。
<bean id="hello" class="com.app.Hello"><property name="userDir" value="#{T(System).getProperty('user.dir')}"/></bean>
对于系统属性而言,在bean定义中使用时有一个内置的变量可以使用叫systemProperties,而且在使用时不需要加“#”,即不需要以“#systemProperties”的形式出现。所以上述示例也可以是如下这样。
<bean id="hello" class="com.elim.learn.spring.bean.Hello"><property name="userDir" value="#{systemProperties['user.dir']}"/></bean>
23.4.1 引用其它bean的属性
在进行bean定义时,我们也可以通过表达式引用其它bean定义的属性。如下示例中我们就在定义id为world的bean的key属性时通过表达式引用了名为hello的bean的key属性,即world的key属性也将被赋予值“abc”。
<bean id="hello" class="com.app.Hello"><property name="key" value="abc"/></bean><bean id="world" class="com.app.World"><property name="key" value="#{hello.key}"/></bean>
23.4.2 基于注解配置的使用
在基于注解配置的bean定义中我们也可以使用SpEl表达式进行某些定义。在基于注解配置bean定义时我们可以使用@Value注解定义在方法或属性上来指定对应的值。此时我们就可以使用对应的表达式,当然不使用表达式也是可以的。如下示例中我们就通过@Value指定了userDir和key的值。其中userDir的值的定义使用了SpEl表达式,而key的值的定义是直接定义的。
public class Hello {@Value("#{systemProperties['user.dir']}")private String userDir;@Value("abc")private String key;public String getUserDir() {return userDir;}public void setUserDir(String userDir) {this.userDir = userDir;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}}
(注:本文是基于Spring4.1.0所写)
- Spring(23)——SPEL表达式(四)
- (四)Spring SPEL表达式
- Spring(23)——SPEL表达式(一)
- Spring(23)——SPEL表达式(二)
- Spring(23)——SPEL表达式(三)
- Spring-10 , Spring表达式语言(SpEL)
- Spring 框架表达式语言(SpEL)
- Spring 的El 表达式 (SpEL)
- (六)Spring表达式语言SpEl
- SpEL(Spring Expression Language)表达式语言
- Spring 表达式语言 (Spring Expression Language) SpEL
- Spring 表达式语言 (Spring Expression Language) SpEL
- Spring表达式语言(Spring Expression Language,SpEL)
- Spring 表达式语言 (Spring Expression Language) SpEL
- Spring 表达式语言 (Spring Expression Language) SpEL
- Spring3.0 —— 表达式语言(SpEL)
- spring学习笔记4——SpEL表达式
- Spring3.1——Spring表达式语言SpEL
- Linux:安装jdk(tar)
- python-----奇怪的国家
- SylixOS周期定时抖动分析
- Spring加载properties文件的两种方式
- jsp+servlet实现文件的上传功能
- Spring(23)——SPEL表达式(四)
- 两条Linux命令彻底杀死Oracle
- Java设计模式--策略模式【Strategy Pattern】
- Nodejs Serialport文档翻译
- 为什么 Kotlin 调用 java 时可以使用 Lambda? —— SAM 转换机制的介绍
- 【学习摘记】马士兵bbs初级版_课时13_登录页面:演示如何盗取网上资源
- 结合thinkphp5与hplus(h+)写的一个带权限的后台管理系统
- 保留关键字(Reserved Words)导致的Jpa保存错误
- Python 爬虫-爬取pixiv特定搜索结果的所有作品-抓取 分析 下载