Spring中的refreshContext源碼分析
前言
在SpringBoot啟動(dòng)流程中,主要的兩個(gè)階段是初始化SpringApplication對象以及SpringApplication.run方法執(zhí)行的內(nèi)容
今天主要細(xì)講的是SpringApplication.run中的刷新容器refreshContext方法
refreshContext()
還是老辦法,先梳理它的大體流程,將不太重要的舍去。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ... // Prepare the bean factory for use in this context. //設(shè)置beanFacotry 和加載一些特殊bean的處理類, prepareBeanFactory(beanFactory); // 一些web項(xiàng)目的bean處理類 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //重要,喚醒 BeanFactoryPostProcessor的實(shí)現(xiàn)類 invokeBeanFactoryPostProcessors(beanFactory); ... // Register bean processors that intercept bean creation. //重要,將BeanPostProcessor的bean定義注冊進(jìn)來 registerBeanPostProcessors(beanFactory); ... // Initialize event multicaster for this context. //再次創(chuàng)建一個(gè)廣播器 initApplicationEventMulticaster(); ... // Check for listener beans and register them. //注冊listener到上述的心廣播器中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //重要,創(chuàng)建單例bean finishBeanFactoryInitialization(beanFactory); ... } }
那么整體上就分為一下幾步
- 對beanFacotry進(jìn)行設(shè)置
- 對benFactory在做一些定制處理(比如加載一些web容器對bean的處理類)
- 喚醒beanFactoryPostProcessor的一些列實(shí)現(xiàn)類
- 創(chuàng)建一個(gè)新廣播器
- 將Listener加入到這個(gè)新廣播器中(注意,這的Listener將會(huì)比我們上一篇所說的多的多,至于原因 在喚醒那一步里面)
- 將所有找到的單例類,都創(chuàng)建處理(這步內(nèi)容也比較多,對于加載Bean的分析 將新啟一篇文章進(jìn)行說明)
prepareBeanFactory()
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //添加了一個(gè)BeanPostProcessor實(shí)例ApplicationContextAwareProcessor // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //指定特定依賴的返回結(jié)果 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. //添加了一個(gè)BeanPostProcessor實(shí)例ApplicationListenerDetector beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); ... }
老辦法 ,逐一分析。
第一步,添加了一個(gè)BeanPostProcessor實(shí)例ApplicationContextAwareProcessor
ApplicationContextAwareProcessor //這個(gè)bean處理器就是在實(shí)現(xiàn)了 EnvironmentAware.class EmbeddedValueResolverAware.class ResourceLoaderAware.class ApplicationEventPublisherAware.class MessageSourceAware.class ApplicationContextAware.class //的類實(shí)例化之前喚醒對應(yīng)的接口方法
指定特定依賴的返回結(jié)果添加了一個(gè)BeanPostProcessor實(shí)例ApplicationListenerDetector
這個(gè)實(shí)例主要是檢查bean是否實(shí)現(xiàn)了ApplicationListener,如果實(shí)現(xiàn)了就將它添加到監(jiān)聽器集合中
前面我們說了也可以通過spring.factories這個(gè)文件添加ApplicationListenr
這里又提供了一種方式,但是這種通過ApplicationListenerDetector來加載的方式 會(huì)讓listener丟失一部分事件(因?yàn)樵跊]有加載Bean之前還有很多事件),如果需要監(jiān)聽非常前面的事件,還是要通過spring.factories這個(gè)文件添加
這里都是講處理類加載進(jìn)來,并沒有執(zhí)行對應(yīng)方法。真正訪問還在后面,前面只是準(zhǔn)備階段
invokeBeanFactoryPostProcessors()
喚醒所有的BeanFactoryPostProcessor實(shí)例 ,這個(gè)與下面的registerBeanPostProcessor將會(huì)以獨(dú)立的章節(jié)來分析(原因還是那個(gè)原因。。。 里面的內(nèi)容有點(diǎn)多)。
registerBeanPostProcessor()
將BeanPostProcessor實(shí)例注冊進(jìn)來
registerListeners()
protected void registerListeners() { // Register statically specified listeners first //加載老的listener for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //加載新的listenner // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... //發(fā)送默認(rèn)的事件集 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
這一步就是將listener注冊到新的廣播器中,分步走。
- 加載老的listener,也就是我們最開始通過spring.factories加載進(jìn)來的監(jiān)聽器
- 加載通過ApplicationListenerDetector注冊進(jìn)來的監(jiān)聽器
- 發(fā)送默認(rèn)事件(就是表明這個(gè)時(shí)間節(jié)點(diǎn)的事件)到監(jiān)聽器中
完成bean的初始化,這個(gè)會(huì)單獨(dú)形成一個(gè)章節(jié),與getBean流程一起講解
總結(jié)
- 準(zhǔn)備BeanFacotry
- BeanFacotry準(zhǔn)備完畢
- 對BeanFacotryPostProcessor進(jìn)行喚醒(因?yàn)锽eanFactory準(zhǔn)備完畢了嘛)
- 注冊BeanPostProcessor(因?yàn)榻酉聛砦覀円獙?shí)例化Bean嘛)
- 對單例Bean進(jìn)行實(shí)例化
你看,邏輯清晰,前后有因果,一下就把整體流程給理順了,而且出乎意料的合理。
到此這篇關(guān)于Spring中的refreshContext源碼分析的文章就介紹到這了,更多相關(guān)refreshContext源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot插件spring tool suite安裝及使用詳解
這篇文章主要介紹了Spring Boot插件spring tool suite安裝及使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08springboot+mybatis plus實(shí)現(xiàn)樹形結(jié)構(gòu)查詢
實(shí)際開發(fā)過程中經(jīng)常需要查詢節(jié)點(diǎn)樹,根據(jù)指定節(jié)點(diǎn)獲取子節(jié)點(diǎn)列表,本文主要介紹了springboot+mybatis plus實(shí)現(xiàn)樹形結(jié)構(gòu)查詢,感興趣的可以了解一下2021-07-07