转载http://blog.csdn.net/gudong2945/article/details/7330642
Spring 3.0 创建了一种新的方式用以配置对象的注入(set注入或者构造参数注入),它便是SpEL (Spring Expression Language)下面我们一一做一介绍。
▲基础特性
——SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpEL.
——1、 字面量的表示
1>整数
[html]
view plain
copy
print
?
- <property name="count" value="#{5}"/>
<span style="font-size:18px;"><property name="count" value="#{5}"/></span>
2>小数
[html]
view plain
copy
print
?
- <property name="frequency" value="#{89.7}"/>
<span style="font-size:18px;"><property name="frequency" value="#{89.7}"/></span>
3>科学计数法
[html]
view plain
copy
print
?
- <property name="capacity" value="#{1e4}"/>
<span style="font-size:18px;"><property name="capacity" value="#{1e4}"/></span>
4>String可以使用单引号或者双引号作为字符串的定界符号。
[html]
view plain
copy
print
?
- <property name="name" value="#{'Chuck'}"/>
- <property name='name' value='#{"Chuck"}'/>
<span style="font-size:18px;"><property name="name" value="#{'Chuck'}"/>
<property name='name' value='#{"Chuck"}'/></span>
5>Boolean
[html]
view plain
copy
print
?
- <property name="enabled" value="#{false}"/>
<span style="font-size:18px;"><property name="enabled" value="#{false}"/></span>
——2、 引用Bean,属性和方法
1>引用其他对象
[html]
view plain
copy
print
?
- <bean id=”saxophone” value=”com.xxx.xxx.Xxx”/>
- <bean ..>
- .
- <property name="instrument" value="#{saxophone}"/>
- .
- <bean/>
<span style="font-size:18px;"><bean id=”saxophone” value=”com.xxx.xxx.Xxx”/>
<bean ..>
.
<property name="instrument" value="#{saxophone}"/>
.
<bean/></span>
通过id:“saxophone”将对象注入到instrument属性中,这与下面的配置是一样的:
[html]
view plain
copy
print
?
- <property name="instrument" ref="saxophone"/>
<span style="font-size:18px;"><property name="instrument" ref="saxophone"/></span>
2> 引用其他对象的属性
[html]
view plain
copy
print
?
- <bean id="carl"
- class="com.springinaction.springidol.Instrumentalist">
- <property name="song" value="#{kenny.song}" />
- </bean>
<span style="font-size:18px;"><bean id="carl"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="#{kenny.song}" />
</bean></span>
kenny是Bean Id 而 song是属性的名字,这样配置就如同我们写了如下的代码
[java]
view plain
copy
print
?
- Instrumentalist carl = new Instrumentalist();
- carl.setSong(kenny.getSong());
<span style="font-size:18px;">Instrumentalist carl = new Instrumentalist();
carl.setSong(kenny.getSong());</span>
3>调用其他方法
[html]
view plain
copy
print
?
- <property name="song" value="songSelector.selectSong()"/>
<span style="font-size:18px;"><property name="song" value="songSelector.selectSong()"/></span>
调用了BeanId为“songSelector”的对象的selectSong()方法,并将返回值注入到song属性中。或者还可以链式操作。如下:
[html]
view plain
copy
print
?
- <property name="song" value="songSelector.selectSong().toUpperCase()"/>
<span style="font-size:18px;"><property name="song" value="songSelector.selectSong().toUpperCase()"/></span>
如果songSelector.selectSong()返回null的还会抛出异常,为了避免我们要使用?.表达式。这样如果songSelector.selectSong()为null就不会再调用后面的方法了。如下
[html]
view plain
copy
print
?
- <property name="song" value="songSelector.selectSong()?.toUpperCase()"/>
<span style="font-size:18px;"><property name="song" value="songSelector.selectSong()?.toUpperCase()"/></span>
4>调用静态方法
我们已经知道如何通过一个对象调用它的方法了,但是如何调用一个静态方法呢?用T()。它将返回一个 Class object
然后我们再调用相应的方法即可:
[html]
view plain
copy
print
?
- <property name="multiplier" value="T(java.lang.Math).PI"/>
<span style="font-size:18px;"><property name="multiplier" value="T(java.lang.Math).PI"/></span>
▲SpEL支持的运算符号
——1、算数运算符:+, -, *, /, %, ^
[html]
view plain
copy
print
?
- <property name="adjustedAmount" value="#{counter.total + 42}"/>
- <property name="adjustedAmount" value="#{counter.total - 20}"/>
- <property name="circumference" value="#{2 * T(java.lang.Math).PI * circle.radius}"/>
- <property name="average" value="#{counter.total / counter.count}"/>
- <property name="remainder" value="#{counter.total % counter.count}"/>
- <property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}"/>
<span style="font-size:18px;"><property name="adjustedAmount" value="#{counter.total + 42}"/>
<property name="adjustedAmount" value="#{counter.total - 20}"/>
<property name="circumference" value="#{2 * T(java.lang.Math).PI * circle.radius}"/>
<property name="average" value="#{counter.total / counter.count}"/>
<property name="remainder" value="#{counter.total % counter.count}"/>
<property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}"/></span>
加号还可以用作字符串连接
[html]
view plain
copy
print
?
- <property name="fullName" value="#{performer.firstName + ' ' + performer.lastName}"/>
<span style="font-size:18px;"><property name="fullName" value="#{performer.firstName + ' ' + performer.lastName}"/></span>
——2、比较运算符: <, >, ==, <=, >=, lt, gt, eq, le, ge
[html]
view plain
copy
print
?
- <property name="equal" value="#{counter.total == 100}"/>
<span style="font-size:18px;"><property name="equal" value="#{counter.total == 100}"/></span>
不可以使用<和>号,应为在xml中它有特殊的含义,我们使用lt和gt代替
[html]
view plain
copy
print
?
- <property name="hasCapacity" value="#{counter.total le 100000}"/>
<span style="font-size:18px;"><property name="hasCapacity" value="#{counter.total le 100000}"/></span>
——3、 逻辑运算符号: and, or, not, |
[html]
view plain
copy
print
?
- <property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 10000}"/>
- <property name="outOfStock" value="#{!product.available}"/>
- <property name="outOfStock" value="#{not product.available}"/>
<span style="font-size:18px;"><property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 10000}"/>
<property name="outOfStock" value="#{!product.available}"/>
<property name="outOfStock" value="#{not product.available}"/></span>
——4、 If-else运算符:?: (ternary), ?: (Elvis)
〇最基本的 ?:(这如同我们在使用EL表达式语言):
[html]
view plain
copy
print
?
- <property name="instrument" value="#{songSelector.selectSong() == 'Jingle Bells' ? piano : ' Jingle Bells '}"/>
<span style="font-size:18px;"><property name="instrument" value="#{songSelector.selectSong() == 'Jingle Bells' ? piano : ' Jingle Bells '}"/></span>
〇变体的 ?:
<property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}"/>
上下两种是同一语义,但下面的明显简洁
[html]
view plain
copy
print
?
- <property name="song" value="#{kenny.song ?: 'Greensleeves'}"/>
<span style="font-size:18px;"><property name="song" value="#{kenny.song ?: 'Greensleeves'}"/></span>
——5、 正则表达式:matches
[html]
view plain
copy
print
?
- <property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/>
<span style="font-size:18px;"><property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/></span>
表达式返回逻辑值,如果匹配返回true,否则返回false
▲SpEL对集合的支持
——环境
有实体City定义如下:
[java]
view plain
copy
print
?
- package com.habuma.spel.cities;
- public class City {
- private String name;
- private String state;
- private int population;
- }
<span style="font-size:18px;">package com.habuma.spel.cities;
public class City {
private String name;
private String state;
private int population;
}</span>
Xml中有如下定义
[html]
view plain
copy
print
?
- <util:list id="cities">
- <bean class="com.habuma.spel.cities.City"
- p:name="Chicago" p:state="IL" p:population="2853114"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Atlanta" p:state="GA" p:population="537958"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Dallas" p:state="TX" p:population="1279910"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Houston" p:state="TX" p:population="2242193"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Odessa" p:state="TX" p:population="90943"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="El Paso" p:state="TX" p:population="613190"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Jal" p:state="NM" p:population="1996"/>
- <bean class="com.habuma.spel.cities.City"
- p:name="Las Cruces" p:state="NM" p:population="91865"/>
- </util:list>
<span style="font-size:18px;"><util:list id="cities">
<bean class="com.habuma.spel.cities.City"
p:name="Chicago" p:state="IL" p:population="2853114"/>
<bean class="com.habuma.spel.cities.City"
p:name="Atlanta" p:state="GA" p:population="537958"/>
<bean class="com.habuma.spel.cities.City"
p:name="Dallas" p:state="TX" p:population="1279910"/>
<bean class="com.habuma.spel.cities.City"
p:name="Houston" p:state="TX" p:population="2242193"/>
<bean class="com.habuma.spel.cities.City"
p:name="Odessa" p:state="TX" p:population="90943"/>
<bean class="com.habuma.spel.cities.City"
p:name="El Paso" p:state="TX" p:population="613190"/>
<bean class="com.habuma.spel.cities.City"
p:name="Jal" p:state="NM" p:population="1996"/>
<bean class="com.habuma.spel.cities.City"
p:name="Las Cruces" p:state="NM" p:population="91865"/>
</util:list></span>
——1、 获取Collection中的某个对象
〇通过下标访问,如下:
[html]
view plain
copy
print
?
- <property name="chosenCity" value="#{cities[2]}"/>
<span style="font-size:18px;"><property name="chosenCity" value="#{cities[2]}"/></span>
我们就会获得population为"1279910"的city(记住下标从0开始)
〇下标可以通过变量指定,如下:
[html]
view plain
copy
print
?
- <property name="chosenCity" value="#{cities[T(java.lang.Math).random() * cities.size()]}"/>
<span style="font-size:18px;"><property name="chosenCity" value="#{cities[T(java.lang.Math).random() * cities.size()]}"/></span>
〇如果是从Map中获得,可指定key值,如下
[html]
view plain
copy
print
?
- <property name="chosenCity" value="#{cities['Dallas']}"/>
<span style="font-size:18px;"><property name="chosenCity" value="#{cities['Dallas']}"/></span>
〇也可以通过key访问properties的值,如下
[html]
view plain
copy
print
?
- <util:properties id="settings" location="classpath:settings.properties"/>
- <property name="accessToken" value="#{settings['twitter.accessToken']}"/>
<span style="font-size:18px;"><util:properties id="settings" location="classpath:settings.properties"/>
<property name="accessToken" value="#{settings['twitter.accessToken']}"/></span>
〇可以通过下标访问systemEnvironment和SystemProperties中的值
[html]
view plain
copy
print
?
- <property name="homePath" value="#{systemEnvironment['HOME']}"/>
<span style="font-size:18px;"><property name="homePath" value="#{systemEnvironment['HOME']}"/></span>
〇如果在jre运行时配置了-Dapplication.home=/etc/myapp,我们可以通过如下方式访问
[html]
view plain
copy
print
?
- <property name="homePath" value="#{systemProperties['application.home']}"/>
<span style="font-size:18px;"><property name="homePath" value="#{systemProperties['application.home']}"/></span>
〇通过下标获取String串中的某个字符
[html]
view plain
copy
print
?
- 'This is a test'[3]
<span style="font-size:18px;">'This is a test'[3]</span>
——2、获取Collection中的子集-通过条件筛选(注意新对象是一个新的Collection)
1>筛选子集(.?[])
[html]
view plain
copy
print
?
- <property name="bigCities" value="#{cities.?[population gt 100000]}"/>
<span style="font-size:18px;"><property name="bigCities" value="#{cities.?[population gt 100000]}"/></span>
2>获取第一个(.^[])
[html]
view plain
copy
print
?
- <property name="aBigCity" value="#{cities.^[population gt 100000]}"/>
<span style="font-size:18px;"><property name="aBigCity" value="#{cities.^[population gt 100000]}"/></span>
3>获取最后一个(.$[])
[html]
view plain
copy
print
?
- <property name="aBigCity" value="#{cities.$[population gt 100000]}"/>
<span style="font-size:18px;"><property name="aBigCity" value="#{cities.$[population gt 100000]}"/></span>
——3、集合的投影(.![])
如果想获得所有城市的名称组成的列表,可用如下操作
[html]
view plain
copy
print
?
- <property name="cityNames" value="#{cities.![name]}"/>
<span style="font-size:18px;"><property name="cityNames" value="#{cities.![name]}"/></span>
将返回"Chicago", "Atlanta", "Dallas"
也可以组合两个列,如下:
[html]
view plain
copy
print
?
- <property name="cityNames" value="#{cities.![name + ', ' + state]}"/>
<span style="font-size:18px;"><property name="cityNames" value="#{cities.![name + ', ' + state]}"/></span>
将返回"Chicago, IL", "Atlanta, GA", and "Dallas, TX".
—— 4、将投影和筛选结合
[html]
view plain
copy
print
?
- <property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/>
<span style="font-size:18px;"><property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/></span>