▲基礎特性
——SpEL使用#{…}作爲定界符,所有在大框號中的字符都將被認爲是SpEL.
——1、 字面量的表示
1>整數
<property name="count" value="#{5}"/>
2>小數
<property name="frequency" value="#{89.7}"/>
3>科學計數法
<property name="capacity" value="#{1e4}"/>
4>String可以使用單引號或者雙引號作爲字符串的定界符號。
<property name="name" value="#{'Chuck'}"/>
<property name='name' value='#{"Chuck"}'/>
5>Boolean
<property name="enabled" value="#{false}"/>
——2、 引用Bean,屬性和方法
1>引用其他對象
<bean id=”saxophone” value=”com.xxx.xxx.Xxx”/>
<bean ..>
.
<property name="instrument" value="#{saxophone}"/>
.
<bean/>
通過id:“saxophone”將對象注入到instrument屬性中,這與下面的配置是一樣的:
<property name="instrument" ref="saxophone"/>
2> 引用其他對象的屬性
<bean id="carl"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="#{kenny.song}" />
</bean>
kenny是Bean Id 而 song是屬性的名字,這樣配置就如同我們寫了如下的代碼
Instrumentalist carl = new Instrumentalist();
carl.setSong(kenny.getSong());
3>調用其他方法
<property name="song" value="songSelector.selectSong()"/>
調用了BeanId爲“songSelector”的對象的selectSong()方法,並將返回值注入到song屬性中。或者還可以鏈式操作。如下:
<property name="song" value="songSelector.selectSong().toUpperCase()"/>
如果songSelector.selectSong()返回null的還會拋出異常,爲了避免我們要使用?.表達式。這樣如果songSelector.selectSong()爲null就不會再調用後面的方法了。如下
<property name="song" value="songSelector.selectSong()?.toUpperCase()"/>
4>調用靜態方法
我們已經知道如何通過一個對象調用它的方法了,但是如何調用一個靜態方法呢?用T()。它將返回一個 Class object
然後我們再調用相應的方法即可:
<property name="multiplier" value="T(java.lang.Math).PI"/>
▲SpEL支持的運算符號
——1、算數運算符:+, -, *, /, %, ^
<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}"/>
加號還可以用作字符串連接
<property name="fullName" value="#{performer.firstName + ' ' + performer.lastName}"/>
——2、比較運算符: <, >, ==, <=, >=, lt, gt, eq, le, ge
<property name="equal" value="#{counter.total == 100}"/>
不可以使用<和>號,應爲在xml中它有特殊的含義,我們使用lt和gt代替
<property name="hasCapacity" value="#{counter.total le 100000}"/>
——3、 邏輯運算符號: and, or, not, |
<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}"/>
——4、 If-else運算符:?: (ternary), ?: (Elvis)
〇最基本的 ?:(這如同我們在使用EL表達式語言):
<property name="instrument" value="#{songSelector.selectSong() == 'Jingle Bells' ? piano : ' Jingle Bells '}"/>
〇變體的 ?:
<property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}"/>
上下兩種是同一語義,但下面的明顯簡潔
<property name="song" value="#{kenny.song ?: 'Greensleeves'}"/>
——5、 正則表達式:matches
<property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/>
表達式返回邏輯值,如果匹配返回true,否則返回false
▲SpEL對集合的支持
——環境
有實體City定義如下:
package com.habuma.spel.cities;
public class City {
private String name;
private String state;
private int population;
}
Xml中有如下定義
<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>
——1、 獲取Collection中的某個對象
〇通過下標訪問,如下:
<property name="chosenCity" value="#{cities[2]}"/>
我們就會獲得population爲"1279910"的city(記住下標從0開始)
〇下標可以通過變量指定,如下:
<property name="chosenCity" value="#{cities[T(java.lang.Math).random() * cities.size()]}"/>
〇如果是從Map中獲得,可指定key值,如下
<property name="chosenCity" value="#{cities['Dallas']}"/>
〇也可以通過key訪問properties的值,如下
<util:properties id="settings" location="classpath:settings.properties"/>
<property name="accessToken" value="#{settings['twitter.accessToken']}"/>
〇可以通過下標訪問systemEnvironment和SystemProperties中的值
<property name="homePath" value="#{systemEnvironment['HOME']}"/>
〇如果在jre運行時配置了-Dapplication.home=/etc/myapp,我們可以通過如下方式訪問
<property name="homePath" value="#{systemProperties['application.home']}"/>
〇通過下標獲取String串中的某個字符
'This is a test'[3]
——2、獲取Collection中的子集-通過條件篩選(注意新對象是一個新的Collection)
1>篩選子集(.?[])
<property name="bigCities" value="#{cities.?[population gt 100000]}"/>
2>獲取第一個(.^[])
<property name="aBigCity" value="#{cities.^[population gt 100000]}"/>
3>獲取最後一個(.$[])
<property name="aBigCity" value="#{cities.$[population gt 100000]}"/>
——3、集合的投影(.![])
如果想獲得所有城市的名稱組成的列表,可用如下操作
<property name="cityNames" value="#{cities.![name]}"/>
將返回"Chicago", "Atlanta", "Dallas"
也可以組合兩個列,如下:
<property name="cityNames" value="#{cities.![name + ', ' + state]}"/>
將返回"Chicago, IL", "Atlanta, GA", and "Dallas, TX".
—— 4、將投影和篩選結合
<property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/>