最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA中SpringBoot啟動(dòng)流程分析

 更新時(shí)間:2023年01月19日 08:34:29   作者:Cuzzz  
這篇文章主要介紹了JAVA中SpringBoot啟動(dòng)流程分析的相關(guān)資料,需要的朋友可以參考下

一丶前言

在之前我們學(xué)習(xí)了SpringBoot自動(dòng)裝配如何實(shí)現(xiàn)的,我們總結(jié)了Spring IOC的底層原理。

但是我們還是不知道SpringApplication.run(主類.class, args)到底做了哪些事情。本文將和大家一起看看SpringBoot啟動(dòng)的大致流程,探討SpringBoot留給我們的擴(kuò)展接口

二丶SpringBoot啟動(dòng)流程分析

上面是SpringBoot調(diào)用SpringApplication.run(主類.class, args)啟動(dòng)的源碼,源碼并不復(fù)雜,整體流程大概如下

下面我們依據(jù)此圖,看看這些步驟SpringBoot底層源碼

1.獲取SpringApplicationRunListener實(shí)現(xiàn)類,包裝成SpringApplicationRunListeners

SpringApplicationRunListener是SpringBoot框架中的監(jiān)聽器,在SpringBoot啟動(dòng)到達(dá)對應(yīng)階段的時(shí)候,會回調(diào)starting,started等方法。

為什么SpringBoot不適應(yīng)Spring 里面的ApplicationListener昵,因?yàn)?code>ApplicationListener依賴于Spring容器,@EventListener注解需要EventListenerMethodProcessor這個(gè)BeanFactoryPostProcessor掃描,將對應(yīng)的bean和方法包裝成ApplicationListener注冊到ApplicationContext中(最終注冊到ApplicationEventMulticaster事件多播器中)對于ApplicationListener類型bean則直接走注冊到ApplicationContext的流程,整個(gè)流程只有Spring 容器啟動(dòng)后才能進(jìn)行,如果沒有SpringApplicationRunListener則開發(fā)者無法在SpringBoot啟動(dòng)對應(yīng)階段進(jìn)行一些擴(kuò)展邏輯的回調(diào)。

SpringApplicationRunListeners 可以看成是SpringApplicationRunListener的門面(門面設(shè)計(jì)模式)

其使用List<SpringApplicationRunListener>持有所有的SpringApplicationRunListener,然后starting等方法都是循環(huán)調(diào)用,集合中SpringApplicationRunListener對應(yīng)的方法

SpringBoot如何獲取所有的SpringApplciationListener

這里將從META-INF/spring.factories獲取org.springframework.boot.SpringApplicationRunListener 定義的實(shí)現(xiàn)類全限定類名,然后反射調(diào)用構(gòu)造方法(SpringApplication application, String[] args)進(jìn)行實(shí)例化。隨后將根據(jù)@Order 或者 Ordered接口定義的順序進(jìn)行排序,然后包裝成SpringApplicationRunListeners

注意無法使用@Component注解 標(biāo)注在SpringApplciationListener注解上,來實(shí)現(xiàn)事件的監(jiān)聽,必須在META-INF/spring.factories中定義,并且必須具備構(gòu)造方法(SpringApplication application, String[] args)。

EventPublishingRunListener

SpringApplication#addListeners 允許我們注冊ApplicationListener到SpringBoot中,然后EventPublishingRunListener其內(nèi)部會new 一個(gè)簡單的事件多播器SimpleApplicationEventMulticaster,在對應(yīng)的SpringBoot啟動(dòng)階段,推送事件。下面式如何注冊ApplicationListener

注意這些ApplicationListener不會被注冊到Spring上下文中,意味著不會響應(yīng)Spring上下文推送的事件,除非這個(gè)ApplicationListener是一個(gè)Spring Bean 并且被Spring管理。

下圖是EventPublishingRunListener在SpringBoot啟動(dòng)的不同階段,推送事件

2.SpringApplicationListeners#starting

沒啥好說的,循環(huán)回調(diào)SpringApplicationRunListener#starting方法

3.prepareEnvironment 根據(jù)項(xiàng)目選擇Environment實(shí)現(xiàn)類,并實(shí)例化

在這一步,SpringBoot會根據(jù)類路徑中的類選擇一個(gè)Environment并實(shí)例化,并且根據(jù)當(dāng)前激活的配置,選擇對應(yīng)的配置文件,進(jìn)行解析,并保存到Environment中。下面是SpringBoot選擇Environment的源碼

那么SpringBoot是如何判斷當(dāng)前項(xiàng)目是什么應(yīng)用類型昵?

其實(shí)根據(jù)類路徑下是否具備指定的類,然后得到指定類型,一般我們都是servlet應(yīng)用,會選擇StandardServletEnvironment

4.SpringApplicationListeners#environmentPrepared

2.SpringApplicationListeners#starting

5.createApplicationContext

根據(jù)類路徑指定類推斷使用什么ConfigurableApplicationContext(一般servlet應(yīng)用使用AnnotationConfigServletWebServerApplicationContext)然后實(shí)例化AnnotationConfigServletWebServerApplicationContext

AnnotationConfigServletWebServerApplicationContext#onRefresh方法在Spring容器刷新后會被調(diào)用,這個(gè)方法將啟動(dòng)Tomcat內(nèi)嵌服務(wù)器

6.prepareContext

這個(gè)方法主要會做以下操作

回調(diào)ApplicationContextInitializer#initialize 回調(diào)所有SpringApplicationRunListener#contextPrepared 將主類包裝成BeanDefinition,注冊到Spring容器上下文中 回調(diào)所有SpringApplicationRunListener#contextLoaded

利用SpringApplicationRunListeners回調(diào)SpringApplicationRunListener,同2,不在贅述

6.1從META-INFO/spring.factories中拿所有ApplicationContextInitializer然后回調(diào)initialize方法

在spring上下文refresh方法調(diào)用前,會回調(diào)initialize方法

這里調(diào)用前還會判斷ApplicationContextInitializer定義的泛型,保證5這一步創(chuàng)建的上下文,符合泛型的要求

6.2 將主類包裝成BeanDefinition,注冊到Spring容器上下文中

這一步非常重要,主類上的注解@SpringBootApplication需要ConfigurationClassPostProcessor解析,才能發(fā)揮@Import,@ComponentScan的作用,想要ConfigurationClassPostProcessor處理主類的前提是主類的BeanDefinition需要在Spring容器中。

也就是說SpringBoot的自動(dòng)裝配,和掃描包路徑下的Spring 組件的前提是,主類的BeanDefinition在Spring容器中

這里的BeanDefinitionRegistry,其實(shí)就是來自5這一步的ApplicationContext,一般來說AnnotationConfigServletWebServerApplicationContext內(nèi)部持有了一個(gè)DefaultListableBeanFactory,DefaultListableBeanFactoryBeanDefinitionRegistry的實(shí)現(xiàn)類,其底層使用一個(gè)ConcurrentHashMap維護(hù),key是bean的名稱,value是對應(yīng)的BeanDefinition

當(dāng)資源是一個(gè)Class的時(shí)候,會使用AnnotatedBeanDefinitionReader讀取Class對象,生成BeanDefinition

這一步還支持xml的方式

7.回調(diào)SpringApplicationRunListener#contextLoaded

同2

8.刷新Spring容器上下文

Spring源碼學(xué)習(xí)筆記12——總結(jié)篇IOC,Bean的生命周期,三大擴(kuò)展點(diǎn)》這篇博客做了詳細(xì)的分析

這里會進(jìn)行自動(dòng)裝配和包路徑掃描注冊BeanDefinition,然后實(shí)例化單例bean

9.回調(diào)SpringApplicationRunListener#started

同2

10.callRunners

從spring容器中拿到ApplicationRunner,和CommandLineRunner調(diào)用run方法

三丶SpringApplication,ApplicationContext,BeanFactory 三平面

我們將SpringApplication看作是SpringBoot平面,ApplicationContext看作是Spring平面,BeanFactory看作是Bean工廠平面,SpringBoot啟動(dòng)到觸發(fā)spring容器刷新,然后觸發(fā)BeanFactory實(shí)例化所有單例,非懶加載bean的流程如下

到此這篇關(guān)于JAVA中SpringBoot啟動(dòng)流程分析的文章就介紹到這了,更多相關(guān)JAVA中SpringBoot啟動(dòng)流程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Retrofit源碼層深入分析

    Java Retrofit源碼層深入分析

    這篇文章主要介紹了Java Retrofit源碼層分析,Retrofit是一個(gè)RESTful的HTTP網(wǎng)絡(luò)請求框架的封裝,網(wǎng)絡(luò)請求的工作本質(zhì)上是OkHttp完成,而Retrofit僅負(fù)責(zé)網(wǎng)絡(luò)請求接口的封裝
    2023-01-01
  • Javaweb實(shí)現(xiàn)完整個(gè)人博客系統(tǒng)流程

    Javaweb實(shí)現(xiàn)完整個(gè)人博客系統(tǒng)流程

    這篇文章主要介紹了怎樣用Java來實(shí)現(xiàn)一個(gè)完整的個(gè)人博客系統(tǒng),我們通過實(shí)操上手的方式可以高效的鞏固所學(xué)的基礎(chǔ)知識,感興趣的朋友一起來看看吧
    2022-03-03
  • Java對象數(shù)組定義與用法詳解

    Java對象數(shù)組定義與用法詳解

    這篇文章主要介紹了Java對象數(shù)組定義與用法,結(jié)合實(shí)例形式分析了java對象數(shù)組的概念、功能、定義與使用方法,需要的朋友可以參考下
    2019-08-08
  • 分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據(jù)字典添加緩存

    分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據(jù)字典添加緩存

    這篇文章主要為大家介紹了分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據(jù)字典添加緩存,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 啟用Spring事務(wù)管理@EnableTransactionManagement示例解析

    啟用Spring事務(wù)管理@EnableTransactionManagement示例解析

    這篇文章主要為大家介紹了啟用Spring事務(wù)管理@EnableTransactionManagement示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 在idea中添加JDK的簡單圖文教程

    在idea中添加JDK的簡單圖文教程

    這篇文章主要介紹了如何在IntelliJ IDEA中配置JDK,講解了打開軟件、進(jìn)入Project Structure、選擇SDKs、添加或選擇JDK版本,最后確認(rèn)并重啟IDEA,需要的朋友可以參考下
    2024-12-12
  • 如何集成swagger2構(gòu)建Restful API

    如何集成swagger2構(gòu)建Restful API

    這篇文章主要介紹了如何集成swagger2構(gòu)建Restful API,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • java中面向?qū)ο蟮母拍罴爸R點(diǎn)總結(jié)

    java中面向?qū)ο蟮母拍罴爸R點(diǎn)總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于java中面向?qū)ο蟮母拍罴爸R點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以參考下。
    2021-01-01
  • Spring?BOOT?AOP基礎(chǔ)應(yīng)用教程

    Spring?BOOT?AOP基礎(chǔ)應(yīng)用教程

    這篇文章主要介紹了Spring?BOOT?AOP的使用,文章從相關(guān)問題展開全文內(nèi)容詳情,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • 解決for循環(huán)為空不需要判斷的問題

    解決for循環(huán)為空不需要判斷的問題

    這篇文章主要介紹了解決for循環(huán)為空不需要判斷的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

翁牛特旗| 延安市| 高雄市| 龙海市| 紫云| 乐业县| 措勤县| 榆树市| 株洲县| 克山县| 永定县| 乌拉特后旗| 松江区| 厦门市| 衡水市| 富平县| 盐边县| 如皋市| 迁安市| 广南县| 衢州市| 青海省| 永定县| 淮滨县| 双流县| 甘谷县| 南平市| 常山县| 射阳县| 安庆市| 连城县| 林州市| 黔西县| 工布江达县| 兴城市| 翁牛特旗| 遂宁市| 大宁县| 文安县| 南华县| 宜州市|