深入淺出Spring Bean

前言

本文參考大量網上博主博文,以及郝佳老師的作品總結而成

1. Spring Bean生命週期

以XML配置方式,整個生命週期大致可分爲以下幾步

  1. 初始化容器
  2. Bean屬性注入、更改以及初始化
  3. 容器、Bean初始化成功,開始調用
  4. 關閉容器、銷燬Bean
1.1 初始化容器

該部分即爲Bean提供一個容器環境,先有容器再有Bean,否則Bean將無從存放

  1. 準備更新容器
  2. ClassPathXmlApplicationContext啓動,爲解析XML做準備
  3. 加載XML配置文件
  4. 調用BeanFactoryPostProcessor實現類構造器
  5. BeanFactoryPostProcessor調用postProcessBeanFactory方法
  6. 調用BeanPostProcessor實現類構造器
  7. 調用InstantiationAwareBeanPostProcessorAdapter實現類構造器
  8. DefaultListableBeanFactory
  9. InstantiationAwareBeanPostProcessor調用postProcessBeforeInstantiation方法
  10. 容器初始化成功!
1.2 Bean屬性注入、更改以及初始化
  1. 調用Bean的構造器進行實例化
  2. InstantiationAwareBeanPostProcessor調用postProcessPropertyValues方法
  3. 屬性注入
  4. 調用BeanNameAware.setBeanName
  5. 調用BeanFactoryAware.setBeanFactory()
  6. BeanPostProcessor接口方法postProcessBeforeInitialization對屬性進行更改
  7. 調用InitializingBean.afterPropertiesSet()
  8. 調用bean的init-method屬性指定的初始化方法
  9. BeanPostProcessor接口方法postProcessAfterInitialization對屬性進行更改
  10. InstantiationAwareBeanPostProcessor調用postProcessAfterInitialization方法
  11. 整個容器加載Bean完成,Bean可以使用了!
1.3 Bean的使用

這部分主要依據使用者而言,暫不描述

1.4 關閉容器、銷燬Bean
  1. 調用DiposibleBean.destory()
  2. 調用bean的destroy-method屬性指定的初始化方法

整個Bean從生產到滅亡走完了全部流程

整個Spring生命週期可分爲四個部分

  1. Bean自身方法調用
  2. Bean級生命週期接口方法調用
  3. 容器即生命方法調用
  4. 工廠後處理接口方法調用

2. Spring如何解決bean的循環依賴

所謂的循環依賴是指在運行狀態下,a調用b,b調用a的情況,即兩個或者多個bean互相調用的情況。spring將循環依賴分成三部分:setter循環依賴和容器循環依賴以及構造器循環依賴。

2.1 容器循環依賴:

表示通過構造器注人構成的循環依賴,此依賴是無法解決的,只能拋出BeanCurentlyInCreationException異常表示循環依賴,對於創建完畢的bean將從當前創建bean池中刪除、被清理掉。

2.2 setter循環依賴

表示通過setter方法注入構成的循環依賴。而對於setter注入造成的循環依賴是通過提前暴露鋼完成構造器注入但未完成其他步驟(如setter注入)的bean來完成的,而且只能解決單力作用域bean的循環依賴。即提前暴露一個單例工廠方法,從而使其他bean能夠引用到該bean

2.3 構造器循環依賴

對於“prototype" 作用域bean, Spring 容器無法完成依賴注人,因爲Spring容器不進行緩存"prototype”作用域的bean,因此無法提前暴露-個創建中的bean。對於“singleton" 作用域bean,可以通過“setAllowCircularReferences(false ); "來禁用循環

3. Bean的加載過程

  • 轉換對應的beanName
  • 嘗試從緩存中加載單例,也就是說單例在Spring的同一個容器只會被創建一次,後續在獲取bean的話,就直接從單例緩存中獲取
  • bean的實例化
  • 原型模式的以來堅持
  • 檢測parentBeanFactory
  • 將存儲XML配置文件的GernericBeanDefinition轉換爲RootBeanDefinition,因爲從XML配置文件中讀取到的Bean信息是存儲在前者中的,但是後續Bean處理都是針對於後者的,所以要進行一個轉換
  • 尋找依賴
  • 針對不同的scope進行bean的創建
  • 類型轉換

4. BeanFactory和FactoryBean的區別

顧名思義,BeanFactory是工廠,代表接口用於管理Bean
FactoryBean是Bean,即交由SpringIOC管理的對象,對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生產或者修飾對象生成的工廠Bean,

5. Bean註冊與使用

  1. 註冊Bean有@Component , @Repository , @ Controller , @Service , @Configration等註解,這些註解註解都是把你要實例化的對象轉化成一個Bean,放在IoC容器中,等你要用的時候,它會和上面的@Autowired , @Resource配合到一起,把對象、屬性、方法完美組裝。
  2. 使用Bean,即是把已經在xml文件中配置好的Bean拿來用,完成屬性、方法的組裝;比如@Autowired , @Resource,可以通過byTYPE(@Autowired)、byNAME(@Resource)的方式獲取Bean
    2.1 @Autowired
    Autowired註解默認按類型裝配(即這個註解是屬於spring的),默認情況下必須要求依賴對象必須存在,如果要允許null 值,可以設置它的required屬性爲false,如:@Autowired(required=false)
    Autowired是按照ByType註解使用的bean而ByType的意思是如果容器中存在一個與指定屬性類型相同的bean,那麼將與該屬性自動裝配。就是查找構造器或者方法中的參數,參數的類型匹配了就注入。
    2.2 @Resource
    Resource這個註解是屬於J2EE的,默認安照名稱進行裝配,名稱可以通過name屬性進行指定,
    Resource註解通過屬性名稱自動裝配。spring會檢查set方法,比如你有一個setMaster(),這個方法提供注入,那相應的Bean name或者id 爲master的Bean 就會被注入到協作者(就是類裏面你所定義的引用型成員)中

6. 參考:

簡書,作者Chandler Qian https://www.cnblogs.com/zrtqsk/p/3735273.html
《Spring源碼深度解析》,作者 郝佳

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