Spring 學習筆記(五)運行時注入

直接看代碼示例:

@Bean
public CompactDisc sgtPeppers(){
    return new BlankDisc("Sgt. Pepper's Lonely Hearts Club Bans","The Beatles");
}

這里的 tittle artist 都是硬編碼的,但有的時候窿给,我們可能會希望避免硬編碼值贵白,而是想讓這些值在運行時再確定。為了實現(xiàn)這些功能崩泡,Spring提供了兩種在運行時求值的方式:
-屬性占位符(Property placeholder)禁荒。
-Spring表達式語言(SpEL)。

注入外部的值

//程序清單3.7 使用@PropertySource 注解和Environment
package com.soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties")
public class ExpressiveConfig{
    
    @Autowired
    Environment
    
    @Bean
    public BlankDisc disc(){
        return new BlankDisc(env.getProperty("disc.title"),env.getProperty("disc.artist");
    }
}

在本例中角撞,@PropertySource引用了類路徑中一個名為app.properties的文件呛伴。定義了 title 和 artist,這個屬性會加載到 spring 的 Environment 中谒所,稍后可以從這里檢索屬性热康。同時,在disc()方法中劣领,會創(chuàng)建一個新的BlankDisc姐军,它的構造器參數(shù)是從屬性文件中獲取的,而這是通過調用getProperty()實現(xiàn)的尖淘。
getProperty()方法并不是獲取屬性值的唯一方法奕锌,getProperty()方法有四個重載的變種形式:

String getProperty(String key)
String getProperty(String key, String defaultValue)
T getProperty(String key, Class<T> type)
T getProperty(String key, Class<T> type, T defaultValue)

Environment還提供了幾個與屬性相關的方法,如果你在使用getProperty()方法的時候沒有指定默認值村生,并且這個屬性沒有定義的話惊暴,獲取到的值是null。如果你希望這個屬性必須要定義趁桃,那么可以使用getRequiredProperty()方法辽话,如下所示:

@Bean
public BlankDisc disc(){
    return new BlankDisc(env.getRequireProperty("disc.tltle"),
                         env.getRequireProperty("disc.artist"));
}

在這里,如果disc.title或disc.artist屬性沒有定義的話镇辉,將會拋出IllegalStateException異常屡穗。
如果想檢查一下某個屬性是否存在的話,那么可以調用Environment的containsProperty()方法:

boolean titleExists = env.containsProperty{"disc.title"};

最后忽肛,如果想將屬性解析為類的話村砂,可以使用getPropertyAsClass()方法:

Class<CompactDisc> cdClass = enc.getPropertyAsClass("disc.class",CompactDisc.class);

除了屬性相關的功能以外,Environment還提供了一些方法來檢查哪些profile處于激活狀態(tài):
-String[] getActiveProfiles():返回激活profile名稱的數(shù)組屹逛;
-String[] getDefaultProfiles():返回默認profile名稱的數(shù)組础废;
-boolean acceptsProfiles(String... profiles):如果environment支持給定profile的話汛骂,就返回true。

屬性占位符

Spring一直支持將屬性定義到外部的屬性的文件中评腺,并使用占位符值將其插入到Spring bean中帘瞭。在Spring裝配中,占位符的形式為使用“${.. }”包裝的屬性名稱蒿讥。作為樣例蝶念,我們可以在XML中按照如下的方式解析BlankDisc構造器參數(shù):

<bean id="sgtPeppers" class="soundsystem.BlankDisc" c:_tittle="${disc.title}" c:_artist="${disc.artist}"/>

如果我們依賴于組件掃描和自動裝配來創(chuàng)建和初始化應用組件的話,那么就沒有指定占位符的配置文件或類了芋绸。在這種情況下媒殉,我們可以使用@Value注解,它的使用方式與@Autowired注解非常相似摔敛。比如廷蓉,在BlankDisc類中,構造器可以改成如下所示:

public BlankDisc(@Value("${disc.title}") String title, @Value("${disc.artist}") String artist){
    this.title = title;
    this.artist = artist;
}

為了使用占位符马昙,我們必須要配置一個PropertyPlaceholderConfigurer bean或PropertySourcesPlaceholderConfigurer bean桃犬。從Spring3.1開始,推薦使用PropertySourcesPlaceholderConfigurer行楞,因為它能夠基于Spring Environment及其屬性源來解析占位符攒暇。如下的@Bean方法在Java中配置了PropertySourcesPlaceholderConfigurer:

@Bean
public static PropertySourcePlaceholderConfigurer placeholderConfigurer(){
    return new PropertySourcesPlaceholderConfigurer();
}

如果你想使用XML配置的話,Spring context命名空間中的<context:propertyplaceholder>元素將會為你生成PropertySourcesPlaceholderConfigurer bean

使用Spring表達式語言進行裝配

Spring 3引入了Spring表達式語言(Spring Expression Language子房,SpEL)SpEL擁有很多特性扯饶,包括:
-使用bean的ID來引用bean;
-調用方法和訪問對象的屬性池颈;
-對值進行算術、關系和邏輯運算钓丰;
-正則表達式匹配躯砰;
-集合操作。

SpEL 樣例
SpEL 表達式要放在 “#{ ... }” 之中携丁。

表示字面量

#{3.14159}  //浮點數(shù)
#{9.87E4}  //科學技術法
#{'Hello'}  //String
#{false}   //布爾值

引用 bean琢歇、屬性和方法。

#{sgtPeppers}  //引用 bean
#{sgtPeppers.artist}  //引用 bean 的一個屬性
#{artistSelect.selectArtist()}  //調用方法
#{artistSelect.selectArtist().toUpperCase()}  //改為大寫字母

在表達式中使用類型

T{java.lang.Math}
T{java.lang.Math}.random()

SpEL 運算符


image.png

image.png
#{2 * T(java.lang.Math).PI * circle.radius}
#{scoreboard.score > 1000 ? "Winner!" : "Loser"}

計算正則表達式

#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}

計算集合

#{jukebow.songs[4].title}
#{'This is a test'[3]}  //表示 string 中第四個
//SpEL 提供了查詢運算符 (.?[])
#{jukebox.songs.?[artist eq 'Aerosmith']}
//SpEL 還提供了 (.^[]) (.$[]) 分別用來在集合中查找第一個和最后一個匹配項
#{jukebox.songs.^[artist eq 'Aerosmith']}
//SpEl 提供了投影運算符 (.![]) 從集合中選擇特定的屬性放到另一個集合中
#{jukebox.songs.![title]}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末梦鉴,一起剝皮案震驚了整個濱河市李茫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肥橙,老刑警劉巖魄宏,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異存筏,居然都是意外死亡宠互,警方通過查閱死者的電腦和手機味榛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來予跌,“玉大人搏色,你說我怎么就攤上這事∪幔” “怎么了频轿?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烁焙。 經常有香客問我航邢,道長,這世上最難降的妖魔是什么考阱? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任翠忠,我火速辦了婚禮,結果婚禮上乞榨,老公的妹妹穿的比我還像新娘秽之。我一直安慰自己,他們只是感情好吃既,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布考榨。 她就那樣靜靜地躺著,像睡著了一般鹦倚。 火紅的嫁衣襯著肌膚如雪河质。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天震叙,我揣著相機與錄音掀鹅,去河邊找鬼。 笑死媒楼,一個胖子當著我的面吹牛乐尊,可吹牛的內容都是我干的。 我是一名探鬼主播划址,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扔嵌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夺颤?” 一聲冷哼從身側響起痢缎,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎世澜,沒想到半個月后独旷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年势告,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛇捌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡咱台,死狀恐怖络拌,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情回溺,我是刑警寧澤春贸,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遗遵,受9級特大地震影響萍恕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜车要,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一允粤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翼岁,春花似錦类垫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至榆俺,卻和暖如春售躁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茴晋。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工陪捷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓代兵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缴阎,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容