javascript
Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1
文章目錄
- Pre
- refresh()
- Spring的設(shè)計
- 源碼驗證
Pre
接上文 Spring5源碼 - 03 普通對象對應(yīng)的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源碼分析
refresh()
這里我們只粗略的看一下其中的邏輯,真的很復(fù)雜
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing. 1:準備刷新上下文環(huán)境 prepareRefresh();// Tell the subclass to refresh the internal bean factory. 2:獲取告訴子類初始化Bean工廠ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context. 3:對bean工廠進行填充屬性prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses. 第四:留給子類去實現(xiàn)該接口postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context. 調(diào)用bean工廠的后置處理器.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation. 調(diào)用bean的后置處理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context. 初始化國際化資源處理器. initMessageSource();// Initialize event multicaster for this context. 創(chuàng)建事件多播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses. 這個方法同樣也是留給子類實現(xiàn)的 springboot也是從這個方法進行啟動tomat的.onRefresh();// Check for listener beans and register them. 把我們的事件監(jiān)聽器注冊到多播器上registerListeners();// Instantiate all remaining (non-lazy-init) singletons. 實例化我們剩余的單實例bean.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event. 最后容器刷新 發(fā)布刷新事件(Spring cloud也是從這里啟動的)finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}Spring的設(shè)計
我們接著來看 spring 是在哪一個方法調(diào)用中完成掃描的 即什么時候初始化BeanDefinition, 并且把這個BeanDefinition放到bdMap集合中。
通過debug分析可以得出
invokeBeanFactoryPostProcessors(beanFactory);主要工作
執(zhí)行所有的需要被執(zhí)行的BeanFactoryPostProcessor
1.1 執(zhí)行Spring內(nèi)置的BeanFactoryPostProcessor (完成Bean的掃描) 【其實就是ConfigurationClassPostProcessor】
1.2 執(zhí)行開發(fā)人員提供的BeanFactoryPostProcessor
源碼驗證
再細說一下主要的設(shè)計思想
看方法名 invokeBeanFactoryPostProcessors 也能猜到 主要是執(zhí)行 BeanFactoryPostProcessors
既然是 BeanFactoryPostProcessors , 那就說明有很多 BeanFactoryPostProcessor
BeanFactoryPostProcessor是個接口,spring實現(xiàn)了一部分,當然開發(fā)人員也可以實現(xiàn)BeanFactoryPostProcessor接口。
那Spring該如何決定這些接口實現(xiàn)類的先后順序呢? 這就是Spring IOC 核心的地方。
先說說Spring的幾個比較核心的子類和實現(xiàn)類
主要干的兩個活
舉個例子 ,假設(shè)我們有個自己的類 ,實現(xiàn)了 子類BeanDefinitionRegistryPostProcessor接口
ArtisanTest02 implements BeanDefinitionRegistryPostProcessor那么你不僅要把BeanDefinitionRegistryPostProcessor的接口實現(xiàn),還要實現(xiàn)其父類BeanFactoryPostProcessor接口的方法,那么在調(diào)用invokeBeanFactoryPostProcessors的時候 ,這兩個方法都會被執(zhí)行 。
假設(shè)還有一個類 ,ArtisanTest03 實現(xiàn)了 BeanFactoryPostProcessor 接口
ArtisanTest03 implements BeanFactoryPostProcessor來運行看下效果
總結(jié)
以上是生活随笔為你收集整理的Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5源码 - 03 普通对象
- 下一篇: Spring5源码 - 05 invok