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

SpringBoot Starter機(jī)制及整合tomcat的實(shí)現(xiàn)詳解

 更新時(shí)間:2022年09月08日 10:39:30   作者:天黑請閉眼丶風(fēng)  
這篇文章主要介紹了SpringBoot Starter機(jī)制及整合tomcat的實(shí)現(xiàn),我們知道SpringBoot自己在“后臺”幫我們配置了很多原本需要我們手動去的東西,至于這個(gè)“后臺”是啥,就是Starter機(jī)制

Starter機(jī)制和springboot整合tomcat

Starter機(jī)制

先解釋一下什么是Starter機(jī)制。Starter機(jī)制就是maven工程中pom文件引入了某個(gè)Starter依賴,就能使用對應(yīng)的功能 例如 引入web的starter依賴 ,就可以使用有關(guān)于web方面的功能。

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

那么這個(gè) Starter機(jī)制是怎么運(yùn)作的呢?當(dāng)我們在項(xiàng)目的pom.xml文件中添加某個(gè)Starter依賴時(shí),其實(shí)就是簡單的添加了很多其他的依賴,比如:

  • spring-boot-starter-web:引入了spring-boot-starter、spring-boot-starter-json、spring-boot-starter-tomcat等和Web開發(fā)相關(guān)的依賴包
  • spring-boot-starter-tomcat:引入了tomcat-embed-core、tomcat-embed-el、tomcat-embed-websocket等和Tomcat相關(guān)的依賴包

通過springboot自動配置的原理從META-INF/spring.factories中獲取到tomcat自動配置類。通過各種條件注解類判斷是否滿足加載tomcat自動配置類的條件。這樣就完成了 Starter機(jī)制

如果我們在項(xiàng)目中要用Tomcat,那就依賴spring-boot-starter-web就夠了,因?yàn)樗J(rèn)依賴了spring-boot-starter-tomcat,從而依賴了Tomcat,從而Tomcat相關(guān)的Bean能生效。

而如果不想用Tomcat,那就得這么寫:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

springboot整合tomcat

通過前面SpringBoot的自動配置機(jī)制、Starter機(jī)制,條件注解分析等,我們拿一個(gè)實(shí)際的業(yè)務(wù)案例來串講一下,那就是SpringBoot和Tomcat的整合。

我們知道,只要我們的項(xiàng)目添加的starter為:spring-boot-starter-web,那么我們啟動項(xiàng)目時(shí),SpringBoot就會自動啟動一個(gè)Tomcat。

那么這是怎么做到的呢?

首先我們可以發(fā)現(xiàn),在spring-boot-starter-web這個(gè)starter中,其實(shí)間接的引入了spring-bootstarter-tomcat這個(gè)starter,這個(gè)spring-boot-starter-tomcat又引入了tomcat-embed-core依賴,

所以只要我們項(xiàng)目中依賴了spring-boot-starter-web就相當(dāng)于依賴了Tomcat。

從這個(gè)spring-boot-starter-web依賴中引入了tomcat的依賴

又從tomcat的依賴中引入了tomcat相關(guān)的依賴

那么來看下springboot如何啟動web容器的。

首先我們知道springboot啟動通過SpringApplication.run(MyApplication.class, args);,進(jìn)入run方法,會調(diào)到如下代碼

這個(gè)run方法中的有一個(gè)refreshContext(context);方法。refreshContext(context);方法經(jīng)過一系列調(diào)用到ServletWebServerApplicationContextonRefresh()方法

@Override
	protected void onRefresh() {
		super.onRefresh();
		try {
			// 啟動Tomcat
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}

重點(diǎn)就是createWebServer();方法。這個(gè)方法中就啟動了tomcat

private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			//ServletWebServerFactory 一個(gè)接口  實(shí)現(xiàn)類有TomcatServletWebServerFactory 等等容器工廠
			//通過getWebServerFactory() 獲取到對應(yīng)容器的創(chuàng)建工廠
			ServletWebServerFactory factory = getWebServerFactory();
			//通過實(shí)現(xiàn)類的getWebServer來啟動對應(yīng)的容器
			this.webServer = factory.getWebServer(getSelfInitializer());
			getBeanFactory().registerSingleton("webServerGracefulShutdown",
					new WebServerGracefulShutdownLifecycle(this.webServer));
			getBeanFactory().registerSingleton("webServerStartStop",
					new WebServerStartStopLifecycle(this, this.webServer));
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

createWebServer();中核心代碼是ServletWebServerFactory factory = getWebServerFactory();this.webServer = factory.getWebServer(getSelfInitializer());。我們一步步分析這兩個(gè)方法。

首先ServletWebServerFactory 是一個(gè)接口,它的實(shí)現(xiàn)類有

那么它會用到哪個(gè)實(shí)現(xiàn)類呢?這個(gè)就和ServletWebServerFactory factory = getWebServerFactory();方法有關(guān)

protected ServletWebServerFactory getWebServerFactory() {
		// Use bean names so that we don't consider the hierarchy
		//獲取到ServletWebServerFactory 所有實(shí)現(xiàn)類的bean的名稱 也就是springboot中配置了哪些容器 如tomcat jetty等
		String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
		//如果沒有bean 表示沒有配置容器
		if (beanNames.length == 0) {
			throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
					+ "ServletWebServerFactory bean.");
		}
		//如果bean大于1 表示配置了多個(gè)容器
		if (beanNames.length > 1) {
			throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
					+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
		}
		//最終返回唯一的容器工廠 比如配置了tomcat 那么就返回了TomcatServletWebServerFactory
		return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
	}

這個(gè)方法中,先獲取所有ServletWebServerFactory類型的beanName,如果為空或者大于一個(gè),就會拋異常,也就是說如果配置了tomcat又配置jetty,就會有兩個(gè)ServletWebServerFactory類型的beanName,那么就會拋出異常。

判斷通過后,通過beanName和類型從bean工廠中獲取到唯一的ServletWebServerFactory,然后返回。重點(diǎn)就是ServletWebServerFactory類型的bean是什么時(shí)候配置進(jìn)去的。這個(gè)就是涉及到web的自動配置類。

在MATE-INF/spring.factories中有一個(gè)ServletWebServerFactoryAutoConfiguration的自動配置類。

@EnableConfigurationProperties(ServerProperties.class)注解會去加載ServerProperties

@ConfigurationProperties注解會從配置文件中讀取對應(yīng)的信息到ServerProperties的屬性上,所以我們在配置文件定義端口號,地址等等就會被識別。

ServletWebServerFactoryAutoConfiguration的自動配置類通過@Import注解導(dǎo)入了ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,

EmbeddedTomcat.class定義了TomcatServletWebServerFactory,所以回到之前的getWebServerFactory(),拿到的就是TomcatServletWebServerFactory。然后調(diào)用factory.getWebServer來啟動容器。實(shí)際上就是TomcatServletWebServerFactory的getWebServer方法

public WebServer getWebServer(ServletContextInitializer... initializers) {
		if (this.disableMBeanRegistry) {
			Registry.disableRegistry();
		}
		Tomcat tomcat = new Tomcat();
		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
		tomcat.setBaseDir(baseDir.getAbsolutePath());
		for (LifecycleListener listener : this.serverLifecycleListeners) {
			tomcat.getServer().addLifecycleListener(listener);
		}
		Connector connector = new Connector(this.protocol);
		connector.setThrowOnFailure(true);
		tomcat.getService().addConnector(connector);
		customizeConnector(connector);
		tomcat.setConnector(connector);
		tomcat.getHost().setAutoDeploy(false);
		configureEngine(tomcat.getEngine());
		for (Connector additionalConnector : this.additionalTomcatConnectors) {
			tomcat.getService().addConnector(additionalConnector);
		}
		prepareContext(tomcat.getHost(), initializers);
		return getTomcatWebServer(tomcat);
	}

這個(gè)方法一目了然,就是new Tomcat(),然后啟動。

這大致就是springboot整合tomcat的流程。如果整合的是jetty,那么拿到的ServletWebServerFactory類型就是JettyServletWebServerFactory,過程是一樣的。

總結(jié)

springboot整合tomcat的過程中,首先通過依賴導(dǎo)入了tomcat的相關(guān)依賴。通過ServletWebServerFactoryAutoConfiguration自動配置類,加載EmbeddedTomcat,也就是加載了TomcatServletWebServerFactory。通過TomcatServletWebServerFactory的getWebServer方法啟動tomcat。

到此這篇關(guān)于SpringBoot Starter機(jī)制及整合tomcat的實(shí)現(xiàn)詳解的文章就介紹到這了,更多相關(guān)SpringBoot Starter機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java通過cellstyle屬性設(shè)置Excel單元格常用樣式的全面總結(jié)講解

    Java通過cellstyle屬性設(shè)置Excel單元格常用樣式的全面總結(jié)講解

    在處理Excel文件時(shí),經(jīng)常需要對單元格進(jìn)行樣式設(shè)置,以滿足特定的需求和美化要求,這篇文章主要給大家介紹了關(guān)于Java通過cellstyle屬性設(shè)置Excel單元格常用樣式的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • 使用maven構(gòu)建java9 service實(shí)例詳解

    使用maven構(gòu)建java9 service實(shí)例詳解

    本篇文章主要介紹了使用maven構(gòu)建java9 service實(shí)例詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • 簡單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    簡單實(shí)現(xiàn)Java通訊錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何簡單實(shí)現(xiàn)Java通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • mybatis 有時(shí)update語句執(zhí)行無效的解決方案

    mybatis 有時(shí)update語句執(zhí)行無效的解決方案

    這篇文章主要介紹了在項(xiàng)目里mybatis有時(shí)update語句執(zhí)行無效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Maven安裝及MyEclipse中使用Maven

    Maven安裝及MyEclipse中使用Maven

    這篇文章主要為大家詳細(xì)介紹了Maven安裝步驟,及MyEclipse中如何使用Maven,感興趣的小伙伴們可以參考一下
    2016-07-07
  • java多線程編程之join方法的使用示例

    java多線程編程之join方法的使用示例

    join方法的功能就是使異步執(zhí)行的線程變成同步執(zhí)行。也就是說,當(dāng)調(diào)用線程實(shí)例的start方法后,這個(gè)方法會立即返回,如果在調(diào)用start方法后后需要使用一個(gè)由這個(gè)線程計(jì)算得到的值,就必須使用join方法
    2014-01-01
  • java制作簡單驗(yàn)證碼功能

    java制作簡單驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了java制作簡單驗(yàn)證碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Maven的配置文件pom.xml詳解(含常用plugin)

    Maven的配置文件pom.xml詳解(含常用plugin)

    pom.xml是Maven項(xiàng)目的核心配置文件,它是 項(xiàng)目對象模型 - Project Object Model(POM)的縮寫,本文我們將全面解析pom.xml,了解其結(jié)構(gòu)和屬性,以及如何使用它來管理項(xiàng)目,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • spring 自動裝配和aop的使用

    spring 自動裝配和aop的使用

    這篇文章主要介紹了spring 自動裝配和aop的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • Java中ByteArrayOutputStream亂碼問題解決

    Java中ByteArrayOutputStream亂碼問題解決

    本文主要介紹了Java中ByteArrayOutputStream亂碼問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07

最新評論

广河县| 西充县| 肇州县| 泰来县| 湄潭县| 司法| 襄汾县| 东乌| 永德县| 苍梧县| 二连浩特市| 固原市| 通化市| 台安县| 沙坪坝区| 丹江口市| 刚察县| 阜城县| 衡东县| 祁连县| 昭觉县| 凉城县| 衡水市| 溧水县| 辛集市| 库尔勒市| 齐河县| 壶关县| 平谷区| 台山市| 莱西市| 上杭县| 曲周县| 乐昌市| 宜都市| 东光县| 湖州市| 海口市| 吴忠市| 鄂伦春自治旗| 吉安市|