天天看點

Spring in Action 閱讀(3)—— 進階裝配

環境與profile

Spring引入了bean profile的功能。要使用profile,你首先要将所有不同的bean 定義整理到一個或多個profile之中,在将應用部署到每個環境時,要確定對應的profile處于 激活(active)的狀态。

從Spring 3.2開始,你也可以在 方法級别上使用@Profile注解,與@Bean注解一同使用。這樣的話,就能将這兩個bean的 聲明放到同一個配置類之中,如下所示:

Spring in Action 閱讀(3)—— 進階裝配

同樣上述操作可以利用XML實作。

激活profile

Spring在确定哪個profile處于激活狀态時,需要依賴兩個獨立的屬 性:spring.profiles.active和spring.profiles.default。如果設定了 spring.profiles.active屬性的話,那麼它的值就會用來确定哪個profile是激活的。但 如果沒有設定spring.profiles.active屬性的話,那Spring将會查 找spring.profiles.default的值。如果spring.profiles.active和 spring.profiles.default均沒有設定的話,那就沒有激活的profile,是以隻會建立那 些沒有定義在profile中的bean。

條件化的bean

Spring 4引入了一個新的 @Conditional注解,它可以用到帶有@Bean注解的方法上。如果給定的條件計算結果 為true,就會建立這個bean,否則的話,這個bean會被忽略。

Spring in Action 閱讀(3)—— 進階裝配

@Conditional将會通過Condition接口進行條件對比:

Spring in Action 閱讀(3)—— 進階裝配

處理自動裝配的歧義性

如果不僅有一個bean能夠匹 配結果的話,這種歧義性會阻礙Spring自動裝配屬性、構造器參數或方法參數。可選bean中的某一個設為首選(primary)的bean,或者使用限定符(qualifier)來幫助Spring 将可選的bean的範圍縮小到隻有一個bean。

限定自動裝配的Bean。

在Spring中,可以通過**@Primary**來表達最喜歡的方 案。@Primary能夠與@Component組合用在元件掃描的bean上,也可以與@Bean組合用在 Java配置的bean聲明中。

@Qualifier注解是使用限定符的主要方式。它可以與@Autowired和@Inject協同使 用,在注入的時候指定想要注入進去的是哪個bean。為@Qualifier注解所設定的參數就是想要注入的bean的 ID。

可以添加多個@Qualifier注解來縮減類的範圍,但是Java不允許在同一個條目上重複出現相同類型的多個注解。但是,我們可以建立自定義的限定符注解,借助這樣的注解來表達bean所希望限定的特性,例如,這樣我們将不 再使用@Qualifier(“cold”),而是使用自定義的@Cold注解,

Spring in Action 閱讀(3)—— 進階裝配

bean的作用域

Spring定義了多種作用域,可以基于這些作用域建立bean,包括:

單例(Singleton):在整個應用中,隻建立bean的一個執行個體。

原型(Prototype):每次注入或者通過Spring應用上下文擷取的時候,都會建立一個新 的bean執行個體。

會話(Session):在Web應用中,為每個會話建立一個bean執行個體。

請求(Rquest):在Web應用中,為每個請求建立一個bean執行個體。

就購物車bean來說,會話作用域是最為合适的,因為它與給定的使用者關聯性最大。要指定會 話作用域,我們可以使用@Scope注解,它的使用方式與指定原型作用域是相同的:

Spring in Action 閱讀(3)—— 進階裝配

SCOPE_SESSION常量是會話的seesion,,proxyMode屬性被設定成了ScopedProxyMode.INTERFACES,這表明這個代理要實作ShoppingCart接口,并将調用委托給實作bean。

Spring in Action 閱讀(3)—— 進階裝配

aop:scoped-proxy是與@Scope注解的proxyMode屬性功能相同的Spring XML配置元 素。它會告訴Spring為bean建立一個作用域代理。預設情況下,它會使用CGLib建立目标類的 代理。但是我們也可以将proxy-target-class屬性設定為false,進而要求它生成基于 接口的代理:

Spring in Action 閱讀(3)—— 進階裝配

運作時值注入

我們可能會希望避免寫死值,而是想讓這些值在運 行時再确定。為了實作這些功能,Spring提供了兩種在運作時求值的方式:

屬性占位符(Property placeholder)。 Spring表達式語言(SpEL)。

@PropertySource引用了類路徑中一個名為app.properties的檔案,屬性檔案會加載到Spring的Environment中,稍後可以從這裡檢索屬性。

Spring in Action 閱讀(3)—— 進階裝配

Spring 3引入了Spring表達式語言(Spring Expression Language,SpEL),它能夠以一種強大 和簡潔的方式将值裝配到bean屬性和構造器參數中,

是SpEL表達式要放到“#{ … }”之中,這與屬性占位符有些類 似,屬性占位符需要放到“${ … }”之中。

SpEL表達式可以簡單的調用BEAN對象方法、屬性以及各種不同的值

Spring in Action 閱讀(3)—— 進階裝配

在SpEL中通路類作用域的方法和常量的話,要依賴T()這個關鍵的運算符。T()運算符的真正價值 在于它能夠通路目标類型的靜态方法和常量。

SpEL通過了一進制運算符、二進制運算以及三元運算,同時可以使用正規表達式。

Spring in Action 閱讀(3)—— 進階裝配

其次它還能引用集合

Spring in Action 閱讀(3)—— 進階裝配