Spring 表達式語言 (Spring Expression Language) SpEL

 Spring 3.0 創建了一種新的方式用以配置對象的注入(set注入或者構造參數注入),它便是SpEL (Spring Expression Language)下面我們一一做一介紹。

▲基礎特性

——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]}"/>



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章