在Spring XML配置文件中裝配Bean的屬性和構造參數都是靜態的,而在運行期才知道裝配的值,就可以使用SpEL實現
SpEL表達式的首要目標是通過計算獲得某個值。在計算這個數值的過程中,會使用到其他的值並會對這些值進行操作。
SpEL特性:(1)、使用Bean的ID來引用Bean;(2)、調用方法和訪問對象的屬性;(3)、對值進行算術、關系和邏輯運算;(4)、正則表達式匹配;(5)、集合操作
#{ }標記會提示 Spring這個標記里的內容是SpEL表達式。
最簡單的屬性注入:<property name="count" value="#{5}" />
還可以與非SpEL表達式的值混用:<property name="message" value="The value is #{5}" />
浮點數value="#{89.7}" 科學記數法value="#{1e4}"=====>10000.0
String類型的字面值:<property name="name" value="#{'Tom'}" />或<property name="name" value='#{"Tom"}' /> 單引號和雙引號相互包含的方式使用
布爾類型:<property name="enable" value="#{false}" />
引用Bean:<property name="userDao" value="#{userDao}" />等價於<property name="userDao" ref="userDao" />
引用Bean屬性:<property name="orderOwner" value="#{user.name}" />類似代碼:User user=new User();order.setOrderOwner(user.getName());
引用Bean的方法:<property name="currUser" value="#{userDao.getCurrUser()}" />(假設userDao內有公共方法getCurrUser())
現在如果想把userDao.getCurrUser()得到的當前英文用戶名轉為大寫字母:<property name="currUser" value="#{userDao.getCurrUser().toUpperCase()}" />,這時如果得到的用戶名為空(null),則會拋NullPointerException異常,為了避免異常,可以使用?.代替點(.),如:<property name="currUser" value="#{userDao.getCurrUser()?.toUpperCase()}" />這樣null后面的方法不再執行
SpEL表達式中使用T( )運算符訪問指定類的靜態方法和常量。
如引用Math類的PI常量:<property name="pi" value="#{T(java.lang.Math).PI}" />
如調用Math類的random靜態方法:<property name="randomNumber" value="#{T(java.lang.Math).random()}" />
使用SpEL進行數值運算:
加法:<property name="adjustedAmount" value="#{counter.total+42}" />(把counter Bean的total屬性值與42相加,注意+運算符兩邊必須是數字型)
其他減、乘、整除、求余運算符類似。
使用SpEL進行比較和邏輯表達式運算時,會將得到的布爾型(true或false)賦值給屬性,注意,比較運算符的<、<=、>、>=這些符號含有<、>,在XML中有特殊意義,故使用中需要用文本替代方式。==對應eq、<對應lt、<=對應le、>對應gt、>=對應ge
比較運算符:<property name="equal" value="#{counter.total==100}" />
邏輯表達式(and 、or 、not或!):<property name="largeCircle" value="#{shape.kind=='circle' and shape.perimeter gt 10000}" />
條件表達式(使用三元運算符? : ):<property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}" />
上述條件表達式中kenny.song有重復,可以簡化寫:<property name="song" value="#{kenny.song ? : 'Greensleeves'}" />
正則表達式:<property name="validEmail" value="#{admin.email matches '/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/'}" />
在SpEL中篩選集合
假設有個City類,屬性有name、state、population
在Spring XML中引入util命名空間,定義一個<util:list>集合
<util:list id="cities">
<bean class="cn.hjp.norClass.City">
<property name="name" value="Chicago"></property>
<property name="state" value="IL"></property>
<property name="population" value="2853114"></property>
</bean>
<bean class="cn.hjp.norClass.City">
<property name="name" value="Atlanta"></property>
<property name="state" value="GA"></property>
<property name="population" value="537958"></property>
</bean>
<bean class="cn.hjp.norClass.City">
<property name="name" value="Dallas"></property>
<property name="state" value="TX"></property>
<property name="population" value="1279910"></property>
</bean>
<bean class="cn.hjp.norClass.City">
<property name="name" value="Houston"></property>
<property name="state" value="TX"></property>
<property name="population" value="2242193"></property>
</bean>
<bean class="cn.hjp.norClass.City">
<property name="name" value="Jal"></property>
<property name="state" value="NM"></property>
<property name="population" value="1996"></property>
</bean>
</util:list>
訪問集合成員:<property name="chosenCity" value="#{cities[2]}" /> 選出集合中第三個City
<property name="chosenCity" value="#{cities[T(java.lang.Math).random()*cities.size()]}" />結合SpEL表達式其他方法
[]運算符也可以獲取java.util.Map集合中成員,假設City是Map集合:<property name="chosenCity" value="#{cities['Dallas']}" />
從java.util.Properties集合中取值,通過<util:properties>元素加載properties配置文件,假設文件有內容twitter.accessToken=aadkeudnfsje233sdjfs。獲取方式:<property name="chosenCity" value="#{settings['twitter.accessToken']}" />
Spring還為SpEL創造了兩種特殊的選擇屬性方式:systemEnvironment和systemProperties
systemEnvironment包含了應用程序所在機器上的所有環境變量(其實是一個java.util.Properties集合),如獲取JAVA_HOME路徑:<property name="homePath" value="#{systemEnvironment['JAVA_HOME']}" />
systemProperties包含了java應用程序啟動時所設置的所有屬性(通常通用-D參數)。因此。如果使用-Dapplication.home=/etc/myapp,來啟動JVM,那么通過SpEL獲取:<property name="homePath" value="#{systemProperties['application.home']}" />
使用SpEL獲取字符串某字符:'This is a test'[3]
查詢集合成員:
<property name="bigCities" value="#{cities.?[population gt 100000]}" />得到人口大於100000的城市集合
<property name="aBigCities" value="#{cities.^[population gt 100000]}" />得到人口大於100000的第一個符合條件的大城市
<property name="bigCities" value="#{cities.$[population gt 100000]}" />得到人口大於100000的最后一個符合條件的大城市
投影集合:從集合中選取每個成員的屬性放入一個新的集合中,使用.![]運算符
<property name="cityNames" value="#{cities.![name]}" /> 得到城市的名字並賦予String類型集合
<property name="cityNames" value="#{cities.![name + ', ' + state]}" />屬性拼接,得到如"Chicago,IL"、"Atlanta,GA"、等數據集合
注意:在傳統方式難以實現的情況下可以考慮使用SpEL,不要把過多邏輯放入SpEL表達式中
