上一篇学习笔记结尾提到了Spring3.0引入的新特性,Spring Expression Language (SpEL),可满足运行时动态生成配置参数的要求,本文就此简要介绍下。
SpEL被使用在XML配置文件中,以#{}作为标记,需在引号内使用,如:
<property name="cityNames" value="#{cities.?[population gt 100000].![name+','+state]}" />
从这个例子可以大概了解到SpEL的功能,它从cities数组中取出所有population属性大于100000的city,然后将name和state属性映射到一个新的String数组。
接下来系统的介绍下SpEL的功能:
支持基本数据类型
- 数字型
#{5},#{89.7},#{1e4}
- 布尔型
#{false},#{true}
- 文本型
#{'chuck'}
支持bean相关的操作
- 通过id对bean本身的引用
#{beanId}
- 引用bean属性,需要有对应的getter方法
#{beanId.property}
- 引用bean方法
#{beanId.method()}
- 引用更多的方法
#{beanId.method().toUpperCase()}
注意:为了避免beanId.method()返回空值而抛出NullPointException,可以使用null safe accessor "?."
#{beanId.method()?.toUpperCase()}
对类属性,类方法的操作
- 类属性
#{T(ClassName).staticProperty}
- 类方法
#{T(ClassName).staticMethod()}
支持常用运算符
- 数学运算符:+,-,*,/,%,^
#{counter.total % counter.count}
- 关系运算符:由于"<",">"在XML中具有特殊的含义,因此为避免歧义,推荐使用"lt", "gt", "eq", "le", "ge"替代"<",">","==","<=",">="
#{counter.total le 100000}
- 逻辑运算符:and,or,not/!
#{shape.kind=='circle' and shape.perimeter gt 10000}
- 条件运算符:"?:"
#{kenny.song!=null ? kenny.song : 'Greensleeves'}
- 正则匹配:matches
#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}
支持对collection的处理
- [ ]操作符
数组索引
#{cities[2]}
Map 键值
#{cities['Dallas']}
- 支持对collection进行筛选
".?" 筛选所有符合条件的element,配合关系运算符
#{cities.?[population gt 100000]}
".^" 获得第一个符合条件的element
#{cities.^[population gt 100000]}
".$" 获得最后一个符合条件的element
#{cities.$[population gt 100000]}
".!" 支持取出一部分属性,映射到新的collection
#{cities.![name + ',' + state]}
util命名空间的properties标签支持properties文件的导入
<util:properties id="settings" location="classpath:settings.properties" />
Spring还提供了systemEnvironment,systemProperties,均为java.util.Properties实例,可直接使用
<property name="homePath" value="#{systemProperties['application.home']}"/>
最后要提下SpEL的不利之处,缺乏类型检查可能会造成测试的麻烦,同时IDE也缺少对其的语法检查,因此仅推荐在SpEL确实能够简化工作的情况下使用。
参考书目:
Spring in Action 3rd Edition by Craig Walls