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

SpringBoot 嵌入式web容器的啟動原理詳解

 更新時間:2021年11月09日 10:04:43   作者:AnalogElectronic  
這篇文章主要介紹了SpringBoot 嵌入式web容器的啟動原理詳解,具有很好的參考價值,希望對大家有所幫助。

SpringBoot應用啟動run方法

SpringApplication.java 中執(zhí)行的代碼

@SpringBootApplication
@EnableAsync //使用異步注解@Async 需要在這里加上@EnableAsync
@MapperScan("springboot.dao") //不可或缺作用是掃描dao包下面的所有mapper裝配
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class,args);
    }
}
    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }
    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

在這里插入圖片描述

 private void refreshContext(ConfigurableApplicationContext context) {
        this.refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            } catch (AccessControlException var3) {
            }
        }
    protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext)applicationContext).refresh();
    }

ServletWebServerApplicationContext.java執(zhí)行的方法

    public final void refresh() throws BeansException, IllegalStateException {
        try {
            super.refresh();
        } catch (RuntimeException var2) {
            this.stopAndReleaseWebServer();
            throw var2;
        }
    }
    protected void onRefresh() {
        super.onRefresh();
        try {
            this.createWebServer();
        } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start web server", var2);
        }
    }
 private void createWebServer() {
        WebServer webServer = this.webServer;
        ServletContext servletContext = this.getServletContext();
        if (webServer == null && servletContext == null) {
            ServletWebServerFactory factory = this.getWebServerFactory();
            this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
        } else if (servletContext != null) {
            try {
                this.getSelfInitializer().onStartup(servletContext);
            } catch (ServletException var4) {
                throw new ApplicationContextException("Cannot initialize servlet context", var4);
            }
        }
        this.initPropertySources();
    }
    protected ServletWebServerFactory getWebServerFactory() {
        String[] beanNames = this.getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
        if (beanNames.length == 0) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.");
        } else if (beanNames.length > 1) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
        } else {
            return (ServletWebServerFactory)this.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
        }
    }
    //配置嵌入式的servlet容器
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> MyCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8081);
            }
        };
    }

SpringBoot 2.x 版本

嵌入式Servlet容器自動配置原理以及啟動原理

一、版本說明

Spring Boot 2.x 版本的嵌入式Servlet容器自動配置是通過 WebServerFactoryCustomizer定制器 來定制的,而在Spring Boot 1.x 版本中我們是通過 EmbeddedServletContainerCustomizer 嵌入式的Servlet容器定制器來定制的。由于之前看的資料都是1.x的版本,但是我使用的是2.x,所以在這里記錄一下2.x版本的嵌入式Servlet容器自動配置原理以及啟動原理。

二、總結(jié)

嵌入式Servlet容器自動配置原理以及啟動原理有三大步:

步驟:

  • SpringBoot 根據(jù)導入的依賴信息,自動創(chuàng)建對應的 WebServerFactoryCustomizer(web服務(wù)工廠定制器);
  • WebServerFactoryCustomizerBeanPostProcessor(web服務(wù)工廠定制器組件的后置處理器)獲取所有類型為web服務(wù)工廠定制器的組件(包含實現(xiàn)WebServerFactoryCustomizer接口,自定義的定制器組件),依次調(diào)用customize()定制接口,定制Servlet容器配置;
  • 嵌入式的Servlet容器工廠創(chuàng)建tomcat容器,初始化并啟動容器。

三、嵌入式Servlet容器自動配置原理(以Tomcat為例)

1、首先找到 EmbeddedWebServerFactoryCustomizerAutoConfiguration ,在里面我們可以看到SpringBoot支持的 servlet容器

//SprinBoot支持的servlet容器有三個Tomcat、Jetty、Undertow,但是默認配置的是Tomcat
 
 
//嵌入式的Undertow
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnClass({Undertow.class, SslClientAuthMode.class})
    public static class UndertowWebServerFactoryCustomizerConfiguration {
        public UndertowWebServerFactoryCustomizerConfiguration() {
        }
 
        @Bean
        public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
        }
    }
 
 
//嵌入式的Jetty
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnClass({Server.class, Loader.class, WebAppContext.class})
    public static class JettyWebServerFactoryCustomizerConfiguration {
        public JettyWebServerFactoryCustomizerConfiguration() {
        }
 
        @Bean
        public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new JettyWebServerFactoryCustomizer(environment, serverProperties);
        }
    }
 
//嵌入式的Tomcat
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnClass({Tomcat.class, UpgradeProtocol.class})
    public static class TomcatWebServerFactoryCustomizerConfiguration {
        public TomcatWebServerFactoryCustomizerConfiguration() {
        }
 
        @Bean
        public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
            return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
        }
    }

2、準備環(huán)節(jié)

1)在以下位置打一個斷點

2)、點進 TomcatWebServerFactoryCustomizer 也就是上圖 return 的,然后在里面的如下位置打一個斷點

3)、然后在里面debug程序,我們在控制臺就可以看到如下信息

3、按照上圖從下往上分析。我們啟動springboot應用時,都是直接運行主程序的main方法,然后調(diào)用里面的run方法,如下圖

4、調(diào)用完run方法,回來到 refreshContext 方法,這個方法是幫我們創(chuàng)建IOC容器對象,并且初始化容器,創(chuàng)建容器中的每一個組件

5、在調(diào)用了 reflesh 方法刷新剛才的IOC容器后,來到 onreflesh 方法,調(diào)用createWebServer()方法,創(chuàng)建WebServer

6、來到createWebServer()方法,該方法最終能夠獲取到一個與當前應用(也就是總結(jié)里說的第一步,根據(jù)我們導入的依賴來獲?。┧鶎氲腟ervlet類型相匹配的web服務(wù)工廠,通過工廠就可以獲取到相應的 WebServerFactoryCustomizer (Web服務(wù)工廠定制器)

注:createWebServer()執(zhí)行后,我們其實來到了 EmbeddedWebServerFactoryCustomizerAutoConfiguration,然后根據(jù)條件(配置的依賴)配置哪一個Web服務(wù)器

我們通過查看 ServletWebServerFactory 的子類,可以看到其中三個就是Tomcat、Jetty和Undertow,根據(jù)我們的配置,所以這里獲取到的是 TomcatWebServerFactoryCustomizer

至此,TomcatWebServerFactoryCustomizer組件創(chuàng)建完成,對應的服務(wù)配置類也已添加到IOC容器。

7、因為容器中某個組件要創(chuàng)建對象就會驚動后置處理器 然后就到 WebServerFactoryCustomizerBeanPostProcessor(web服務(wù)工廠定制器組件的后置處理器),該類負責在bean組件初始化之前執(zhí)行初始化工作。它先從IOC容器中獲取所有類型為WebServerFactoryCustomizerBeans(web服務(wù)工廠定制器的組件)

通過后置處理器獲取到的TomcatWebServerFactoryCustomizer調(diào)用customize()定制方法,獲取到Servlet容器相關(guān)配置類ServerProperties,進行自動配置

至此,嵌入式Servlet容器的自動配置完成。

注:從源碼分析可以得出配置嵌入式Servlet容器的兩種解決方案:

1、在全局配置文件中,通過server.xxx來修改和server有關(guān)的配置:

server.port=8081
server.tomcat.xxx...

2、實現(xiàn)WebServerFactoryCustomizer接口,重寫它的customize()方法,對容器進行定制配置:

@FunctionalInterface
public interface WebServerFactoryCustomizer<T extends WebServerFactory> {
    void customize(T factory);
}

四、嵌入式Servlet容器啟動原理(以Tomcat為例)

1、應用啟動后,根據(jù)導入的依賴信息,創(chuàng)建了相應的Servlet容器工廠,創(chuàng)建了TomcatServletWebServerFactory,調(diào)用getWebServer()方法創(chuàng)建Tomcat容器:(其實就是重寫了ServletWebServerFactory里面的getWebServer方法

找到下面的getTomcatWebServer方法

2、然后點進去分析TomcatWebServer的有參構(gòu)造器,執(zhí)行 initialize() 方法

3、點進去就可以發(fā)現(xiàn),里面通過調(diào)用start方法來啟動Tomcat

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA實戰(zhàn)練習之圖書管理系統(tǒng)實現(xiàn)流程

    JAVA實戰(zhàn)練習之圖書管理系統(tǒng)實現(xiàn)流程

    隨著網(wǎng)絡(luò)技術(shù)的高速發(fā)展,計算機應用的普及,利用計算機對圖書館的日常工作進行管理勢在必行,本篇文章手把手帶你用Java實現(xiàn)一個圖書管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-10-10
  • Java JVM內(nèi)存區(qū)域詳解

    Java JVM內(nèi)存區(qū)域詳解

    下面小編就為大家?guī)硪黄趈vm java內(nèi)存區(qū)域的介紹。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-11-11
  • 淺談jvm中的垃圾回收策略

    淺談jvm中的垃圾回收策略

    下面小編就為大家?guī)硪黄獪\談jvm中的垃圾回收策略。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • Java實現(xiàn)多線程聊天室

    Java實現(xiàn)多線程聊天室

    這篇文章主要為大家詳細介紹了Java實現(xiàn)多線程聊天室,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Spring 中使用反射創(chuàng)建 Bean 實例的幾種方式

    Spring 中使用反射創(chuàng)建 Bean 實例的幾種方式

    文章介紹了在Spring框架中如何使用反射來創(chuàng)建Bean實例,包括使用Class.newInstance()、Constructor.newInstance()、工廠方法以及Spring的BeanUtils工具類,文章還強調(diào)了反射操作的注意事項,如異常處理、性能、安全性以及類型安全,感興趣的朋友一起看看吧
    2025-03-03
  • Java反射機制(Reflection)淺析

    Java反射機制(Reflection)淺析

    這篇文章主要介紹了Java反射機制(Reflection)淺析,本文以實例講解Java的反射機制,需要的朋友可以參考下
    2014-07-07
  • Java實現(xiàn)單鏈表反轉(zhuǎn)的多種方法總結(jié)

    Java實現(xiàn)單鏈表反轉(zhuǎn)的多種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)單鏈表反轉(zhuǎn)的多種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Java環(huán)境配置原理全面解析

    Java環(huán)境配置原理全面解析

    下面小編就為大家?guī)硪黄狫ava環(huán)境配置原理全面解析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • nacos注冊中心單節(jié)點ap架構(gòu)源碼解析(最新推薦)

    nacos注冊中心單節(jié)點ap架構(gòu)源碼解析(最新推薦)

    這篇文章主要介紹了nacos注冊中心單節(jié)點ap架構(gòu)源碼解析,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • 解決dubbo注冊到zookeeper速度慢的問題

    解決dubbo注冊到zookeeper速度慢的問題

    這篇文章主要介紹了解決dubbo注冊到zookeeper速度慢的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論

张家口市| 巍山| 济阳县| 巴中市| 保亭| 乐清市| 龙门县| 湘阴县| 湖州市| 津市市| 永顺县| 新化县| 德钦县| 宜宾县| 青铜峡市| 浑源县| 鄂伦春自治旗| 高阳县| 祥云县| 米林县| 利川市| 南平市| 闻喜县| 新竹县| 长白| 通州区| 百色市| 夏河县| 马尔康县| 罗源县| 潞西市| 钦州市| 新田县| 遂川县| 赞皇县| 乌苏市| 普兰县| 泗阳县| 米易县| 博客| 依兰县|