【SpringBoot深入理解源碼】之Bean的實例化解析

縱有疾風來
人生不言棄。

前情回顧
【SpringBoot深入理解源碼】之自定義系統初始化器
【SpringBoot深入理解源碼】之系統監聽器

IOC思想

Spring對Bean的管理就是IOC思想的體現。

  1. 耦合性
  2. 靈活性
  3. 可維護性

Bean的配置方式

XML

首先定義一個實體類和調用Service

public class Student {
    private String name;
    private Integer ago;
    private List<String> classList;
    //set/get/toString...
}
public class Demo1Service {
    private Student student;
    //set/get/toString...
}
  • 無參構造

在這裏插入圖片描述

  • 有參構造

給實體類添加構造函數
在這裏插入圖片描述

  • 靜態工廠

靜態方法注入

<bean id="" class="全限定類名" factory-method="靜態方法">
        //......
</bean>
  • 實例工廠
<bean id="" factory-bean="全限定類名" factory-method="實例方法">
        //......
</bean>

優點

  1. 低耦合
  2. 對象關係清晰
  3. 集中管理

缺點

  1. 配置繁瑣
  2. 開發效率較低
  3. 文件解析耗時

註解

  • @Component聲明
    在這裏插入圖片描述

  • 配置類中使用@Bean
    在這裏插入圖片描述

  • 實現FactoryBean

多實現方法推薦
在這裏插入圖片描述

  • 實現BeanDefinitionRegistryPostProcessor
    在這裏插入圖片描述

  • 實現ImportBeanDefinitionRegistrar

在這裏插入圖片描述
優點

  1. 使用簡單
  2. 開發效率高
  3. 高內聚

缺點

  1. 配置分散
  2. 對象關係不清晰
  3. 配置修改需要重新編譯工程

源碼解讀

關於源碼解讀比較複雜,針對有些解讀的詳細過程可能會專門抽出一章進行解讀。

refresh方法

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}
  1. bean配置讀取加載入口
  2. 完成spring框架啓動流程
  3. 面試重點

prepareRefresh()

  1. 容器狀態設置
  2. 初始化屬性設置
  3. 檢查必備屬性是否存在
@Order(1)
public class FirstInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        //獲取環境
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        //設置環境必備屬性
        environment.setRequiredProperties("name");
    }
}

啓動Springboot,毫無疑問,啓動失敗因爲在Bean解析過程中,需要檢查必備屬性是否都在。而我們配置的name屬性SpringBoot沒有找到。
在這裏插入圖片描述
這時候我們在application.properties中配置,則完美啓動。

name=xxx

obtainFreshBeanFactory()

  1. 設置BeanFactory序列化Id
  2. 獲取BeanFactory

prepareBeanFactory(beanFactory)

  1. 設置beanFactory一些屬性
  2. 添加後置處理器
  3. 設置忽略的自動裝配接口
  4. 註冊一些組件

postProcessBeanFactory(beanFactory)

  1. 子類重寫以在BeanFactory完成創建後做進一步設置

invokeBeanFactoryPostProcessors(beanFactory)

  1. 調用BeanDefinitionRegistryPostProcessor實現向容器內添加bean的定義
  2. 調用BeanFactoryPostProcessor實現向容器bean的定義的添加屬性

registerBeanPostProcessors(beanFactory)

  1. 找到BeanPostProcessor的實現
  2. 排序後註冊進容器中

initMessageSource()

  1. 初始化國際化相關屬性

initApplicationEventMulticaster()

  1. 初始化事件廣播器,註冊到容器當中

onRefresh()

  1. 創建Web容器

registerListeners()

  1. 添加容器內事件監聽器至事件廣播器中
  2. 派發早期還沒處理的事件

finishBeanFactoryInitialization(beanFactory)

  1. 初始化所有剩下的單實例Bean

finishRefresh()

  1. 初始化生命週期處理器
  2. 調用化生命週期處理器onRfresh方法
  3. 發佈ContextRefreshedEvent事件

最後完成對上述操作緩存的清理工作
在這裏插入圖片描述
在這裏插入圖片描述

Bean實例化解析

Bean的實例化解析主要在finishBeanFactoryInitialization(beanFactory)方法內進行

首先進入finishBeanFactoryInitialization方法,getBean進去實例化
在這裏插入圖片描述
實例化調用doGet()方法
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

大概的流程圖

在這裏插入圖片描述

文章持續更新,可以微信搜索「 紳堂Style 」第一時間閱讀,回覆【資料】有我準備的面試題筆記。
GitHub https://github.com/dtt11111/Nodes 有總結面試完整考點、資料以及我的系列文章。歡迎Star。
在這裏插入圖片描述

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