Spring(四)---高級裝配(2)

(四)運行時值的注入
(1)注入外部的值
在Spring中,處理外部值的最簡單的方式就是聲明屬性源並通過Spring的Environment來檢索屬性
這裏寫圖片描述
—->深入瞭解Spring的Environment
getProperty()的四個重載的形式:
這裏寫圖片描述

//getProperty(string key)
Enviroment env;
env.getProperty(disc.title);
//getProperty(string key,String defaultValue) --若Key不存在時,可以設定一個默認值
env.getProperty(disc.title,test);
//env.getProperty(String key,Class<T> type) --可以將key所對應的value值自動轉換類型
int count = env.getProperty(db.connection.count,Integer.class);

方法 描述
getRequriedProperty() 希望該屬性必須要定義,若沒有定義拋異常
containsProperty() 檢查某個屬性是否存在
getPropertyAsClass 將該屬性解析爲類
String[] getActiveProfiles() 返回激活profile名稱的數組
String[] getDefaultProfiles() 返回默認profile名稱的數組
boolean acceptProfiles(String profile) 如果enviroment支持給定的profile的話,就返回true

(2)解析屬性佔位符
Spring一直支持將屬性定義到外部的屬性文件中,並使用佔位符將其插入到Spring bean中.在Spring裝配中,佔位符的形式爲使用”${…}”包裝屬性名稱
例:

//在XML中
<!-- 引入外部資源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置數據源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
   <property name="user" value="${jdbc.user}"></property>
   <property name="password" value="${jdbc.password}"></property>
   <property name="driverClass" value="${jdbc.driverClass}"></property>
   <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
//組件掃描和自動裝配來創建和初始化應用組件,使用@Value註解
//爲了使用佔位符,必須要配置一個PerpertyPlaceholderConfigurer bean或PerpertySourcesPlaceholderConfigurer bean(推薦使用:能夠基於Spring Environment及其屬性源來解析佔位符)


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

在java配置文件配置PerpertySourcesPlaceholderConfigurer
這裏寫圖片描述
(3)使用Spring表達式語言進行裝配
Spring3引入了Spring表達式語言(Spring Expression Language,SpEL),它能夠以強大和簡潔的方式將值裝配到bean的屬性和構造器參數中
SpEL擁有很多特性:

  • 使用bean的ID來引用bean;
  • 調用方法和訪問對象的屬性;
  • 對值進行算術,關係和邏輯;
  • 正則表達式匹配
  • 集合操作
    (1)標識字面值
    SpEL可以用來表示整數字面值,浮點數,String值以及Boolean值
    例 #{3.14159}
    (2)引入bean,屬性和方法
    SpEL可以通過ID引用其他的bean,例如可以使用SpEL將一個bean裝配到另外一個bean的屬性中
    例:
//引入bean的屬性
#{testClass.name}
//引入bean的方法
#{testClass.getName()}
//對於調用方法的返回值來說,我們可以調用它的方法,若調用的方法可能爲Null的話,可能會造成空指針異常,爲了避免空指針異常,可以使用?.作用是若調用的方法爲null,則不執行後面的方法
#{testClass.getName()?.toUpperCase()}

(3)使用靜態方法
如果要在SpEL中訪問靜態方法或常量的話,要使用T()運算符
例:
T(java.lang.Math).PI
(4)SpEL運算符
這裏寫圖片描述
這裏寫圖片描述
(5)計算正則表達式
SpEl通過matches運算符支持表達式中的模糊匹配,matches會返回一個boolean值,匹配返回true,否則返回false
例判斷字符串是否是一個郵箱
這裏寫圖片描述
(6)計算集合
SpEL可以進行集合和數組的操作;

//"[]"運算符用來從集合或數組中按照索引獲取元素
//例1 計算songs集合中第五個(基於零開始)元素的title屬性
#{jukebox.songs[4].title}
//例2 可以從String中獲取一個字符串
#{'This is a test'[3]}   ---> 's'

//SpEL還提供了查詢運算符(.?[]),它會用來對集合進行過濾,得到集合的一個子集
//例3 想得到jukbox中artist屬性爲Aerosmith的所有歌曲
#{jukebox.songs.?[artist eq 'Aerosmith']}

//".^[]和.$[]"分別用來在集合中查詢第一個匹配項和最後一個匹配項
//例4 查找列表中第一個artist屬性爲Aerosmith的歌曲
#{jukebox.songs.^[artist eq 'Aerosmith']}

//投影查詢運算符(.![])
//例5 假設不想要歌曲對象的集合,而是所有歌曲名稱的集合
#{jukebox.songs.![title]}
//例6 獲得Aerosmith所有歌曲的名稱列表
#{jukebox.songs.?[artist eq 'Aerosmith'].![title]}

(五)內部bean

  • 當Bean實例僅僅給一個特定的屬性使用時,可以將其聲明爲內部Bean.內部Bean聲明直接包含在<property><constructor-arg>元素裏,不需要設置任何id或name屬性;
  • 內部Bean不能使用在任何其他地方
    <!-- 聲明使用內部 bean -->
    <bean id="service2" class="com.atguigu.spring.ref.Service">
        <property name="dao">
            <!-- 內部 bean, 類似於匿名內部類對象. 不能被外部的 bean 來引用, 也沒有必要設置 id 屬性 -->
            <bean class="com.atguigu.spring.ref.Dao">
                <property name="dataSource" value="c3p0"></property>
            </bean>
        </property>
    </bean>

(六)繼承Bean配置
- Spring 允許繼承 bean 的配置, 被繼承的 bean 稱爲父 bean. 繼承這個父 Bean 的 Bean 稱爲子 Bean;
- 子 Bean 從父 Bean 中繼承配置, 包括 Bean 的屬性配置;
- 子 Bean 也可以覆蓋從父 Bean 繼承過來的配置;
- 父 Bean 可以作爲配置模板, 也可以作爲 Bean 實例. 若只想把父 Bean 作爲模板, 可以設置 <bean>的abstract 屬性爲 true, 這樣 Spring 將不會實例化這個 Bean;
- 並不是 <bean> 元素裏的所有屬性都會被繼承. 比如: autowire, abstract 等;
- 也可以忽略父 Bean 的 class 屬性, 讓子 Bean 指定自己的類, 而共享相同的屬性配置. 但此時 abstract 必須設爲 true

<bean id="user4" parent="user" p:userName="Bob"></bean>

(七)依賴Bean的配置
- Spring 允許用戶通過 depends-on 屬性設定 Bean 前置依賴的Bean,前置依賴的 Bean 會在本 Bean實例化之前創建好;
- 如果前置依賴於多個 Bean,則可以通過逗號,空格或的方式配置 Bean 的名稱

<bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章