Bean相關問題

IOC&DI概述

1.IOC(Inversion of Control):其思想是反轉資源獲取的方向.傳統的資源查找方式要求組件向容器發起請求查找資源.作爲迴應,容器適時的返回資源.而應用了IOC之後,則是容器主動地將資源推送給它所管理的組件,組件所要做的僅是選擇一種合適的方式來接受資源.這種行爲也被稱爲查找的被動形式
2.DI(Dependency Injection)——IOC的另一種表述方式:即組件以一些預先定義好的方式(例如setter方法)接受來自如容器的資源注入.相對於IOC而言,這種表述更直接

配置bean

  1. 配置形式:基於XML文件的方式;基於註解的方式
    1. ApplicationContext主要實現類:
      1. ClassPathXmlApplicationContext:從類路徑下加載配置文件
      2. FileSystemXmlApplicationContext:從文件系統中加載配置文件
    2. ConfigurableApplicationContext擴展於ApplicationContext,新增加兩個主要方法:refresh()和close(),讓ApplicatContext具有啓動、刷新、和關閉上下文的能力
    3. ApplicationContext在初始化上下文時就實例化所有單例的Bean
    4. WebApplicationContext是專門爲WEB應用而準備的,它允許從相對於WEB根目錄的路徑中完成初始化工作

自動裝配

  1. Spring IOC容器可以自動裝配Bean.需要做的僅僅是<bean>的autowire屬性裏指定自動裝配的模式
    1. byType(根據類型自動裝配):若IOC容器中有多個與目標Bean類型一致的Bean.在這種情況下,Spring將無法判定拿個Bean最合適該屬性,所以不能執行自動裝配(需要唯一)
    2. byName(根據名稱自動裝配):必須將目標Bean的名稱和屬性名設置的完全相同(需要唯一)
    3. constructor(通過構造器自動裝配):當Bean中存在多個構造器時,此種自動裝配方式將會很複雜(不推薦使用
  2. 自動裝配不夠靈活

Bean之間的關係(繼承、依賴)

  1. 繼承:使用<bean>標籤的parent屬性
    1. Spring允許繼承bean的配置,被繼承的bean稱爲父bean.繼承這個父Bean的Bean稱爲子Bean
    2. 子Bean從父Bean中繼承配置,包括Bean的屬性配置
    3. 子Bean也可以覆蓋從父Bean繼承過來的配置
    4. 父Bean可以作爲配置模板,也可以作爲Bean實例.若只想把父Bean作爲模板,可以設置<bean>的abstract屬性爲true,這樣Spring將不會實例化這個Bean
    5. 並不是<bean>元素裏的所有屬性都會被繼承.比如:autowire,abstract等
    6. 可以忽略父Bean的class屬性,讓子Bean指定自己的類,而共享相同的屬性配置.但此時abstract必須設爲true
  2. 依賴:Spring允許用戶通過depends-on屬性設定Bean前置依賴的Bean,前置依賴的Bean會在本Bean實例化之前創建好
    1. 如果前置依賴於多個Bean,則可以通過逗號,空格或的方式配置Bean的名稱

Bean的作用域:singleton;prototype;WEB環境作用域

  1. 用bean標籤的scope屬性設置作用域
  2. 默認是單例模式/singleton。(每次調用都是同一個實例,在加在配置文件時就會創建實例)
  3. prototype:原型。每次都會獲取一個新的實例,在請求實例時纔會創建實例

使用外部屬性文件

  1. 在配置文件裏配置Bean時,有時需要在Bean的配置裏混入系統部署的細節信息(例如:文件路徑,數據源配置信息等)。而這些部署細節實際上需要和Bean配置相分離
  2. Spring提供了一個PropertyPlaceholderConfigurer的BeanFactory後置處理器(即<context:property-placeholder>標籤),這個處理器允許用戶將Bean配置的部分內容外移到屬性文件中。可以在Bean配置文件裏使用形式爲${var}的變量,並使用這些屬性來替代變量
  3. Spring還允許在屬性文件中使用${propName},以實現屬性之間的相互引用

SpEL(Spring表達式語言)

  1. Spring表達式語言(簡稱SpEL):是一個支持運行時查詢和操作對象圖的強大的表達式語言
  2. 語法類似EL:SpEL使用#{…}作爲定界符,所有在大括號中的字符都將被認爲是SpEL
  3. SpEL爲bean的屬性進行動態賦值提供了便利
  4. 通過SpEL可以實現:
    1. 通過bean的id對bean進行引用
    2. 調用方法以及引用對象中的屬性
    3. 計算表達式的值
    4. 正則表達式的匹配
  5. 字面量的表示:
    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}" / >
  6. 引用Bean、屬性和方法:
    1. 引用其他對象
    2. 引用其他對象的屬性
    3. 調用其他方法,還可以鏈式操作
    4. 調用靜態方法或靜態屬性:通過T(className)調用一個類的靜態方法,它將返回一個Class Object,然後再調用相應的方法或屬性
  7. SpEL支持的運算符號
    1. 算術運算符:+、-、*、/、%、^
    2. 加號還可以用作字符串連接
    3. 比較運算符:<、>、==、<=、>=、lt、gt、eq、le、ge
    4. 邏輯運算符:and、or、not、|
    5. if-else運算符:?:(temary),?:(Elvis)
    6. if-else的變體
    7. 正則表達式:matches

Spring管理Bean的生命週期

  1. Spring IOC容器可以管理Bean的生命週期,Spring允許在Bean生命週期的特定點執行定製的任務
  2. Spring IOC容器對Bean的生命週期進行管理的過程:
    1. 通過構造器或工廠方法創建Bean實例
    2. 爲Bean的屬性設置值和對其他Bean的引用
    3. 調用Bean的初始化方法
    4. Bean可以使用了
    5. 當容器關閉時,調用Bean的銷燬方法
  3. 在Bean的聲明裏設置init-method和destory-method屬性,爲Bean指定初始化和銷燬方法
  4. 創建Bean後置處理器
    1. Bean後置處理器允許在調用初始化方法前後對Bean進行額外的處理
    2. Bean後置處理器對IOC容器裏的所有Bean實例逐一處理,而非單一實例。其典型應用是:檢查Bean屬性的正確性或根據特定的標準更改Bean的屬性
    3. 對Bean後置處理器而言,需要實現Interface BeanPostProcessor接口。在初始化方法被調用前後,Spring將把每個Bean實例分別傳遞給上述接口的以下兩個方法:postprocessafterinitialization(Object bean, String beanName)和postprocessbeforeinitialization(Object bean, String beanName)
    4. 可以在以上兩個方法中修改返回的Bean,甚至返回一個新的Bean
    5. 配置Bean的後置處理器不需要配置id,IOC容器會自動識別BeanPostProcessor
  5. Spring IOC容器對Bean的生命週期進行管理的過程:
    1. 通過構造器或工廠方法創建Bean實例
    2. 爲Bean的屬性設置值和對其他Bean的引用
    3. 將Bean實例傳遞給Bean後置處理器的和postprocessbeforeinitialization方法
    4. 調用Bean實例傳遞給Bean後置處理器的postprocessafterinitialization方法
    5. Bean可以使用了
    6. 當容器關閉時,調用了Bean的銷燬方法

通過工廠方法配置Bean

  1. 靜態工廠方法:
    1. 在bean的class屬性裏指定擁有該工廠方法的Bean
    2. 在factory-method屬性裏指定該工廠方法的名稱
    3. 使用construtor-arg元素爲工廠方法傳遞方法參數
  2. 實例工廠方法:將對象的創建過程封裝到另外一個對象實例的方法裏。當客戶端需要請求對象時,只需要簡單的調用該實例方法而不需要關心對象的創建細節
  3. 要聲明通過實例工廠方法創建的Bean
    1. 在bean的factory-bean屬性裏指定擁有該工廠方法的Bean
    2. 在factory-method屬性裏指定該工廠方法的名稱
    3. 使用construtor-arg元素爲工廠方法傳遞方法參數

通過FactoryBean配置Bean

  1. 自定義的FactoryBean需要實現FactoryBean接口
  2. 配置文件中通過FactoryBean來配置Bean的實例,class指向FactoryBean的屬性,但實際返回的實例卻是FactoryBean的getObject()方法返回的實例

通過註解配置Bean

  1. 組件掃描(component scanning):Spring能夠從classpath下自動掃描,偵測和實例化具有特定註解的組件
    1. 當在組件類上使用了特定的註解之後,還需要在Spring的配置文件中聲明<context:component-scan>
      1. base-package屬性指定一個需要掃描的基類包,Spring容器將會掃描這個基類包裏及其子包中的所有類
      2. 當需要掃描多個包時,可以使用逗號分隔
      3. 如果僅希望掃描特定的類而非基包下的所有類,可使用resource-pattern屬性指定特定的類,實例:<context:component-scan base-package="com.beans" resource-pattern="autowire/*.class">
      4. <context:include-filter>子節點表示要包含的目標類,使用這個節點時需要將use-default-filters屬性設置爲false
      5. <context:exclude-filter>子節點表示要排除在外的目標類
      6. <context:component-scan>下可以擁有若干個<context:include-filter><context:exclude-filter>子節點
    2. <context:include-filter><context:exclude-filter>子節點支持多種類型的過濾表達式:
類別 示例 說明
annotation com.XxxAnnotation 所有標註了XxxAnnotation的類,該類型採用目標類是否標註了某個註解進行過濾
assignable com.XxxService 所有繼承或擴展XxxService的類,該類型採用目標類是否繼承或擴展某個特定類進行過濾
aspectj com.*Service+ 所有類名以Service結束的類及繼承或擴展它們的類。該類型採用AspejctJ表達式進行過濾
regex com.\anno.* 所有com.anno包下的類,該類型採用正則表達式根據類的類名進行過濾
custom com.XxxTypeFilter 採用XxxTypeFilter通過代碼的方式定義過濾規則。該類必須實現org.springframework.core.type.TypeFilter接口

2. 特定組件包括:
1. @Component:基本註解,標識了一個受Spring管理的組件
2. @Respository:標識持久層組件
3. @Service:標識服務層(業務層)組件
4. @Controller:標識表現層組件
3. 對於掃描到的組件,Spring有默認的命名策略:使用非限定類名,第一個字母小寫.也可以在註解中通過value屬性值標識組件的名稱
4. 組件裝配:<context:component-scan>元素還會自動註冊AutowiredAnnotationBeanPostProcessor實例,該實例可以自動裝配具有@Autowired和@Resource、@Inject註解的屬性
1. @Autowired註解自動裝配具有兼容類型的單個Bean屬性
1. 構造器、普通字段(即使是非public),一切具有參數的方法都可以應用@Autowired註解
2. 默認情況下,所有使用@Autowired註解的屬性都需要被設置,當Spring找不到匹配的Bean裝配屬性時,會拋出異常,若一屬性允許不被設置,可以設置@Autowired註解的required屬性爲false
3. 默認情況下,當IOC容器裏存在多個類型兼容的Bean時,通過類型的自動裝配將無法工作.此時可以在@Qualifler註解裏提供Bean的名稱.Spring允許對方法的入參標註@Qualifiter已指定注入Bean的名稱
4. @Autowired註解也可以應用在數組類型的屬性上,此時Spring將會把所有匹配的Bean進行自動裝配
5. @Autowired註解也可以應用在集合屬性上,此時Spring讀取該集合的類型信息,然後自動裝配所有與之兼容的Bean.
6. @Autowired註解在java.util.Map上時,若該Map的鍵值爲String,那麼Spring將自動裝配與之Map值類型兼容的Bean,此時Bean的名稱作爲鍵值
2. 使用@Resource或@Inject自動裝配Bean
1. Spring還支持@Resource和@Inject註解,這兩個註解和@Autowired註解的功能類似
2. @Resource註解要求提供一個Bean名稱的屬性,若該屬性爲空,則自動採用標註處的變量或方法名作爲Bean的名稱
3. @Inject和@Autowired註解一樣也是按類型匹配注入的Bean,但沒有reqired屬性
4. 建議使用@Autowired註解


泛型依賴注入

Spring 4.x中可以爲子類注入子類對應的泛型類型的成員變量的引用

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