日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

分析SpringBoot的啟動原理

瀏覽:19日期:2023-04-25 18:52:28

背景

1> 大家都知道SpringBoot是通過main函數啟動的,這里面跟蹤代碼到處都沒有找到while(true),為什么啟動后可以一直跑?

2> SpringBoot默認使用tomcat作為web容器。大家也可以通過在pom文件中exclusion掉tomcat,denpendency jetty 的方法來使用jetty。那SpringBoot是怎么做到在不同web容器之間切換的呢?

3> 傳統的web容器比如jetty本質上是直接通過java start.jar 來啟動,之后來加載spring上下文的,SpringBoot通過main函數是怎么來啟動web容器的呢?

本文就這三個問題展開論述。

問題1分析

問題1很簡單,啟動后一直跑是因為啟動了線程池。原理就是有非deamon的線程在跑。Java虛擬機規范定義要等所有用戶線程都運行完才會退出。

所以這個原理就和下面啟動線程池一樣

分析SpringBoot的啟動原理

程序員修煉之道教我們:不要假定,要證明。雖然jetty使用線程池是常識,我們也來跟蹤下源碼,看看線程池是在哪里初始化的:

org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory類里,創建Server的使用使用線程池作為初始化參數。然后創建了socket連接來監聽端口。(對于socket連接有之前沒接觸過的,可以自己查一下。建議動手實踐。《Java異常處理總結》這篇文章里有不錯的簡單小例子可以實操下。)

分析SpringBoot的啟動原理

到這里,大家應該都明白了為什么啟動后一直不停。但是又有疑問了:JettyServletWebServerFactory是個什么東東?

問題2分析

關于問題2,我們寫個最簡單的類來debug一下:

分析SpringBoot的啟動原理

進入SpringAppication.run的源碼可以看到,里面創建了一個context,默認是AnnotationConfigServletWebServerApplicationContext。一初始化,在Bean定義里就加載了spring開天辟地的5個Bean。

分析SpringBoot的啟動原理

繼續向下執行走到AbstractApplicationContext的refresh方法,執行到onRefresh時,你進入方法里發現實際上執行的是

ServletWebServerApplicationContext的onFresh

分析SpringBoot的啟動原理

這里面實際只做了一件事:創建web服務。

分析SpringBoot的啟動原理

進入這個方法,debug到getWebServerFactory

分析SpringBoot的啟動原理

來看一下:

分析SpringBoot的啟動原理

獲取的正式JettyServletWebServerFactory。為啥不是TomcatServlet呢?ServletWebServerFactoryAutoConfiguration的源碼很好的說明了這個問題。源碼的大意是當tomcat依賴存在就用tomcat,不然就按順序找jetty存不存在,不存在再找Undertow存不存在。找到了就返回這個bean作為Servlet的工廠類。

@Configuration@AutoConfigureOrder(-2147483648)@ConditionalOnClass({ServletRequest.class})@ConditionalOnWebApplication( type = Type.SERVLET)@EnableConfigurationProperties({ServerProperties.class})@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})public class ServletWebServerFactoryAutoConfiguration { public ServletWebServerFactoryAutoConfiguration() { } @Bean public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) { return new ServletWebServerFactoryCustomizer(serverProperties); } @Bean @ConditionalOnClass( name = {'org.apache.catalina.startup.Tomcat'} ) public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) { return new TomcatServletWebServerFactoryCustomizer(serverProperties); } public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; public BeanPostProcessorsRegistrar() { } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (beanFactory instanceof ConfigurableListableBeanFactory) {this.beanFactory = (ConfigurableListableBeanFactory)beanFactory; } } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (this.beanFactory != null) {this.registerSyntheticBeanIfMissing(registry, 'webServerFactoryCustomizerBeanPostProcessor', WebServerFactoryCustomizerBeanPostProcessor.class);this.registerSyntheticBeanIfMissing(registry, 'errorPageRegistrarBeanPostProcessor', ErrorPageRegistrarBeanPostProcessor.class); } } private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) { if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);beanDefinition.setSynthetic(true);registry.registerBeanDefinition(name, beanDefinition); } } }}

至此第二個問題也真相大白。

問題3分析

第三個問題是傳統的web容器比如jetty本質上是直接通過java start.jar 來啟動,之后來加載spring上下文的,SpringBoot通過main函數是怎么來啟動web容器。

這個問題在前面問題分析過程中也給了很多線索。我們來回顧下:SpringApplication.run里會創建Spring的應用上下文,默認是AnnotationConfigServletWebServerApplicationContext。首先會加載Spring開天辟地的5個Bean。然后它初始化各種Bean工廠。

SpringBoot在ServletWebServerApplicationContext中重載了onRefresh方法,除了以前Spring默認的onRefresh方法外還增加了createWebServer方法,在這個方法中對Web容器進行了初始化工作。

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.boot.version}</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </exclusion> </exclusions></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> <version>${spring.boot.version}</version> <exclusions> <exclusion> <groupId>org.eclipse.jetty.aggregate</groupId> <artifactId>jetty-all</artifactId> </exclusion> </exclusions></dependency>

因為選擇servlet容器是類似于使用基于條件的注解方式。因為當exclusion掉tomcat后,只有jetty滿足條件,所以會加載JettyServletWebServerFactory。

通過getWebServer方法會new一個WebServer對象,new對象的方法會調用initialize方法,在這個方法中會對容器進行初始化并啟動。

而容器啟動的基本原理就是創建個線程池和網絡套接字。用線程去處理套接字讀寫的內容。

總結

文本用帶有少許說明的三個問題開場展開論述,實際是使用了麥肯錫大法中的SCQA架構。

SCQA架構是金字塔模型里面突出的一個論述方法,即“情境(Situation)、沖突(Complication)、問題(Question)、答案(Answer)”。可以幫助我們在陳述事實時條理更為清晰、有效。

SCQA其實只是麥肯錫做了總結。這個方法李清照都在用:

昨夜雨疏風驟,濃睡不消殘酒 (情境)

試問卷簾人,渠道海棠依舊(沖突)

知否,知否(問題)

應是綠肥紅瘦(答案)

文章正文看似一步步回答問題,實際上在講述怎樣去看spring源碼,了解spring原理的一個過程。即:帶著問題去看,debug跟蹤源碼驗證 的方法。

以上就是分析SpringBoot的啟動原理的詳細內容,更多關于SpringBoot 啟動原理的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品亚洲片在线播放| 久久精品av| 亚洲一区二区三区免费在线观看| 久久久五月天| 国产一区二区三区成人欧美日韩在线观看| 国产在线成人| 99精品美女| 久久国产免费看| 播放一区二区| 色88888久久久久久影院| 国产一区亚洲| 亚洲香蕉久久| 国产精品久久久久久妇女 | 国产美女久久| 久久精品国产99国产精品| 成人在线黄色| 日韩精品一卡| 日韩精品一级二级| 91精品国产自产观看在线| 99久久亚洲精品蜜臀| 欧美在线91| 国产精品地址| 电影亚洲精品噜噜在线观看| 国产无遮挡裸体免费久久| 国产精品一线| 久久天堂成人| 中文视频一区| 国产精品麻豆久久| 亚洲深夜福利| 精品国产亚洲日本| 91久久久精品国产| 国产麻豆精品久久| 欧美日韩国产免费观看视频| 国产欧美三级| 影音先锋久久精品| 国产一级成人av| 久久久久久久久丰满| 精品一区二区三区的国产在线观看| 免费在线观看视频一区| 国精品一区二区三区| 日韩视频一二区| 成人国产精品| 日本亚洲最大的色成网站www| 亚洲精品美女91| 麻豆国产精品| 亚洲欧美网站| 成人日韩av| 亚洲毛片在线| 美女网站一区| 一区在线视频观看| 欧美91精品| 国产欧美在线| 久久都是精品| 亚洲综合在线电影| 国产日韩一区二区三区在线 | 国产99在线| 热久久免费视频| 日本免费一区二区三区四区| 国产日韩欧美三级| 国产欧美午夜| 亚洲女同一区| 日韩精品91| 国产精品久久国产愉拍| 日韩影院在线观看| 美女少妇全过程你懂的久久| 高清av一区| 国产丝袜一区| 日韩精品福利一区二区三区| 宅男噜噜噜66国产日韩在线观看| 日韩专区欧美专区| 四虎精品永久免费| 欧美肉体xxxx裸体137大胆| 精品视频在线你懂得| 精品国产乱码久久久久久1区2匹 | 91av一区| 国产精品日韩久久久| 精品72久久久久中文字幕| 日本视频在线一区| 久久不见久久见中文字幕免费| 国产精品午夜av| 亚洲一卡久久| 女主播福利一区| 亚洲天堂黄色| 999国产精品视频| 久久中文视频| 亚洲二区视频| 91精品一区二区三区综合| 午夜在线精品| 啪啪亚洲精品| 综合一区二区三区| 精品久久网站| 欧美片网站免费| 日本中文字幕不卡| 美女国产精品久久久| 婷婷综合一区| 婷婷五月色综合香五月| 美女国产一区二区三区| 91亚洲无吗| 91精品福利观看| 国产精品手机在线播放| 国产精品久久久久久av公交车| 高清在线一区| 久久精品国内一区二区三区水蜜桃| 美女亚洲一区| 欧美成人精品| 一区在线免费观看| 亚洲欧美日韩国产综合精品二区 | 麻豆一区二区三| 国产精品地址| 亚洲永久av| 久久亚洲在线| 99re国产精品| 日韩有码av| 麻豆视频久久| 亚洲va久久久噜噜噜久久| 亚洲一区二区三区中文字幕在线观看| 成人亚洲一区| 日韩欧美二区| 最新日韩av| 日本一区福利在线| 欧美特黄视频| 亚洲欧美不卡| 国产美女视频一区二区| 日韩综合一区| 欧美日韩国产亚洲一区| 亚洲精品第一| 久久精品三级| 亚洲二区视频| 日本视频中文字幕一区二区三区| 午夜免费一区| 久久午夜影视| 欧美国产日韩电影| 久久三级视频| 日韩区欧美区| 日本综合字幕| 亚洲三级精品| 国产精品久久免费视频| 日韩国产网站| 日韩精品视频中文字幕| 日韩一区二区免费看| 亚洲黄色网址| 亚洲二区三区不卡| 日韩二区三区在线观看| 国产一区二区三区不卡视频网站| 国产精品久久久一区二区| 蜜桃视频一区二区| 国产亚洲一卡2卡3卡4卡新区| 亚洲精一区二区三区| 麻豆久久一区| 免费在线观看日韩欧美| 久久三级毛片| 五月天久久久| 久久超碰99| 天堂成人免费av电影一区| 久久99蜜桃| 日韩影院在线观看| 都市激情国产精品| 精品久久国产一区| 欧美精品一区二区久久| 国产精品日韩精品中文字幕| 九色精品91| 久久亚洲黄色| 亚洲青青久久| 免费精品国产的网站免费观看| 影视先锋久久| 欧美天堂在线| 国产精品视频一区二区三区| 久久国产毛片| 国产精品调教视频| 视频一区二区三区在线| 综合日韩av| 特黄毛片在线观看| 国产第一亚洲| 亚洲专区视频| 欧美福利专区| 亚洲精品**中文毛片| 国产精品综合| 日韩欧美久久| 麻豆国产精品| 亚洲黄色中文字幕| 奇米狠狠一区二区三区| 红桃视频亚洲| 欧美黄色网页| 激情综合婷婷| 国产精品一区二区三区www| 免费在线看一区| 国产亚洲一区二区三区啪| 黄色国产精品| 久久天堂成人| 欧美香蕉视频| zzzwww在线看片免费| 久久91视频| 美女视频黄久久| 国产乱人伦丫前精品视频| 亚洲乱码一区| 国产亚洲欧洲| 在线亚洲免费| 蜜桃久久av| 久久亚洲风情| 在线综合亚洲|