縱有疾風來
人生不言棄。
前情回顧
【SpringBoot深入理解源碼】之自定義系統初始化器
【SpringBoot深入理解源碼】之系統監聽器
IOC思想
Spring對Bean的管理就是IOC思想的體現。
- 耦合性
- 靈活性
- 可維護性
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>
優點
- 低耦合
- 對象關係清晰
- 集中管理
缺點
- 配置繁瑣
- 開發效率較低
- 文件解析耗時
註解
-
@Component聲明
-
配置類中使用@Bean
-
實現FactoryBean
多實現方法推薦
-
實現BeanDefinitionRegistryPostProcessor
-
實現ImportBeanDefinitionRegistrar
優點
- 使用簡單
- 開發效率高
- 高內聚
缺點
- 配置分散
- 對象關係不清晰
- 配置修改需要重新編譯工程
源碼解讀
關於源碼解讀比較複雜,針對有些解讀的詳細過程可能會專門抽出一章進行解讀。
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();
}
- bean配置讀取加載入口
- 完成spring框架啓動流程
- 面試重點
prepareRefresh()
- 容器狀態設置
- 初始化屬性設置
- 檢查必備屬性是否存在
- 必備屬性?
在前面講【SpringBoot深入理解源碼】之自定義系統初始化器中說到了怎麼實現系統初始化器。
@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()
- 設置BeanFactory序列化Id
- 獲取BeanFactory
prepareBeanFactory(beanFactory)
- 設置beanFactory一些屬性
- 添加後置處理器
- 設置忽略的自動裝配接口
- 註冊一些組件
postProcessBeanFactory(beanFactory)
- 子類重寫以在BeanFactory完成創建後做進一步設置
invokeBeanFactoryPostProcessors(beanFactory)
- 調用BeanDefinitionRegistryPostProcessor實現向容器內添加bean的定義
- 調用BeanFactoryPostProcessor實現向容器bean的定義的添加屬性
registerBeanPostProcessors(beanFactory)
- 找到BeanPostProcessor的實現
- 排序後註冊進容器中
initMessageSource()
- 初始化國際化相關屬性
initApplicationEventMulticaster()
- 初始化事件廣播器,註冊到容器當中
onRefresh()
- 創建Web容器
registerListeners()
- 添加容器內事件監聽器至事件廣播器中
- 派發早期還沒處理的事件
finishBeanFactoryInitialization(beanFactory)
- 初始化所有剩下的單實例Bean
finishRefresh()
- 初始化生命週期處理器
- 調用化生命週期處理器onRfresh方法
- 發佈ContextRefreshedEvent事件
最後完成對上述操作緩存的清理工作
Bean實例化解析
Bean的實例化解析主要在finishBeanFactoryInitialization(beanFactory)方法內進行
首先進入finishBeanFactoryInitialization方法,getBean進去實例化
實例化調用doGet()方法
大概的流程圖
文章持續更新,可以微信搜索「 紳堂Style 」第一時間閱讀,回覆【資料】有我準備的面試題筆記。
GitHub https://github.com/dtt11111/Nodes 有總結面試完整考點、資料以及我的系列文章。歡迎Star。