圖解:SpringBoot Spring Dubbo 啓動過程

OverView

Java程序員都應清楚Spring生命週期,這是Java程序員的基礎知識。緊緊掌握這些知識點這不單單能夠應付面試,更重要的是,能夠更好的分析實際工做中的問題。
本文將把SpringBoot、Spring、Dubbo結合起來,分析他們的啓動流程。整個過程大體會長下面這個樣子。
屏幕快照 2020-01-01 下午10.26.07
下面,咱們就分別看看SpringBoot的啓動過程。程序員

SpringBoot的啓動過程

SpringBoot能夠理解爲Spring的啓動程序,啓動程序的入口方法爲SpringApplication.run(),詳細以下:
面試

A: 通知 Listener,start
B: 建立EnviromentEnviroment是整個應用的配置以及Profile的承載類
C: 建立容器
D: 初始化容器, ApplicationContext.refresh()即爲容器初始化入口
E: 空方法
F: 通知 Listener,started
G: 通知 Listener,running
經過觀察發現:SpringBoot.run()中代碼步驟,大體能夠概括總結爲兩種行爲動做:app

  • SpringApplicationRunListeners調用(藍色)
  • 建立和初始化容器(綠色)兩部分
    因此我的以爲SpringApplicationRunListeners表明了SpringBoot的生命週期,這個生命週期描述了SpringBoot的啓動過程,如:建立初始化Enviroment,建立初始化容器

總結:SpringBoot的生命週期,以下圖:post

Spring啓動過程

在SpringBoot啓動過程當中,會建立、刷新ApplicationContext。結合上面的流程後,以下圖:

這裏的refreshContext,就是Spring容器建立初始化的過程,下面咱們詳細介紹一下此過程。spa

Spring中有一個類AbstractApplicationContext,全部類型的ApplicationContext,例如ClassPathXmlApplicationContextFileSystemXmlApplicationContext AnnotationConfigApplicationContext 都是繼承此類。
AbstractApplicationContext 中有一個著名的方法refresh(),Spring容器的設計者們將容器啓動過程抽象到了這個方法中,也就是AbstractApplication.refresh()方法中。 全部類型的ApplicationContext都會進入此方法。
debug

Dubbo的啓動過程

Dubbo程序是以Spring Beans的形式存在於Spring容器中,隨着Spring容器啓動而啓動。
對於Dubbo業務方來講,主要有兩個重要的Bean,ServiceBeanReferenceBean,他們各自會調用Service.export()Reference.get()來暴露服務以及引用遠程服務。
在使用這兩個Bean的時候,Dubbo的設計者爲了讓用戶能夠以Annotation的方式方便的使用,他們利用Spring的衆多擴展點,在Spring容器啓動過程當中,自動發現、註冊、實例化了ServiceBeanReferenceBean設計

具體流程圖以下:
3d

BeanDefinition的註冊

EnableDubbo
若是咱們是使用Annotation方式使用Dubbo,那麼會在SpringConfig類中添加@EnableDubbo註解,這個註解會利用@Import註解的BeanDefinition註冊機制,向容器中註冊DubboConfigBindingBeanPostProcessor ServiceAnnotationBeanPostProcessor ReferenceAnnotationBeanPostProcesser這三個重要的postProcessor來完成ServiceBeanReferenceBean的建立。代理

@Import註解是由下面的ConfigurationClassPostProcessor讀取執行的。code

ConfigurationClassPostProcessor
Spring在容器的refresh()方法執行過程當中,當BeanFactory準備好後就會執行invokeBeanFactoryPostProcessors(BeanFactory),若是debug源碼會發現剛開始候容器只有ConfigurationClassPostProcessor 這一個BeanFactoryPostProcessor,它的做用,按照源碼的說法是:Bootstrapping processing of @Configuration 。源碼註解大概意思是:它是第一個加載進容器並被執行的BeanFactoryPostProcessor,而後他做爲Configuration引導過程,自動導入程序中的其餘Configuration相關類。
原來,@Configuration @Import就是由它讀取執行的。

ServiceAnnotationBeanPostProcessor
時機:

  1. ServiceAnnotationBeanPostProcessor是一個BeanFactoryPostProcessor在容器invokeBeanFactoryPostProcessors()過程當中,會被執行。

做用:以@Service做爲過濾條件,掃描指定scanBasePackages,向容器註冊ServiceBean。在refresh完成的時候,會向容器中發送ContextRefershEvent,ServiceBean實例會監聽此事件,而後執行服務export過程。

擴展點:BeanFactoryPostProcessor

Bean初始化

ReferenceAnnotationBeanPostProcessor
時機:

  1. 在容器初始化完成後,會實例化容器中的單例非懶初始化Bean。
  2. 在實例化Bean之後,初始化Bean屬性前會調用populateBean()方法,執行AnnotationInjectedBeanPostProcessor爲注入依賴的屬性。
  3. ReferenceAnnotationBeanPostProcessor就是繼承自AnnotationInjectedBeanPostProcessor,此時它會隨着一塊兒執行。

動做:

  1. 加載掃描目錄scanBasePackages下的類,找到@Reference所註解的字段,爲其注入值。
  2. 注入的值爲業務接口的動態代理類,動態代理(InvocationHandler)的邏輯是調用ReferenceBean.get()方法,建立真正的Invoker
  3. 因此最終注入了封裝了遠程調用邏輯的Invoker

Sping擴展點:BeanPostProcessor AnnotationInjectedBeanPostProcessor

DubboConfigBindingBeanPostProcessor
做用:爲配置承載類:ApplicationConfigModuleConfig RegistryConfig ProtocolConfig等自動狀態配置
Spring擴展點:BeanPostProcessor

相關文章
相關標籤/搜索