亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java?SpringBoot核心源碼詳解

 更新時間:2021年12月28日 17:20:22   作者:波波烤鴨  
這篇文章主要為大家介紹了Java?SpringBoot核心源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

SpringBoot源碼主線分析

我們要分析一個框架的源碼不可能通過一篇文章就搞定的,本文我們就來分析下SpringBoot源碼中的主線流程。先掌握SpringBoot項目啟動的核心操作,然后我們再深入每一個具體的實現(xiàn)細節(jié),注:本系列源碼都以SpringBoot2.2.5.RELEASE版本來講解

1.SpringBoot啟動的入口

當我們啟動一個SpringBoot項目的時候,入口程序就是main方法,而在main方法中就執(zhí)行了一個run方法。

@SpringBootApplication
public class StartApp {
	public static void main(String[] args) {
		SpringApplication.run(StartApp.class);
	}
}

2.run方法

然后我們進入run()方法中看。代碼比較簡單

	public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		// 調用重載的run方法,將傳遞的Class對象封裝為了一個數(shù)組
		return run(new Class<?>[] { primarySource }, args);
	}

調用了重載的一個run()方法,將我們傳遞進來的類對象封裝為了一個數(shù)組,僅此而已。我們再進入run()方法。

	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		// 創(chuàng)建了一個SpringApplication對象,并調用其run方法
		// 1.先看下構造方法中的邏輯
		// 2.然后再看run方法的邏輯
		return new SpringApplication(primarySources).run(args);
	}

在該方法中創(chuàng)建了一個SpringApplication對象。同時調用了SpringApplication對象的run方法。這里的邏輯有分支,先看下SpringApplication的構造方法中的邏輯

3.SpringApplication構造器

我們進入SpringApplication的構造方法,看的核心代碼為

	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		// 傳遞的resourceLoader為null
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		// 記錄主方法的配置類名稱
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		// 記錄當前項目的類型
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		// 加載配置在spring.factories文件中的ApplicationContextInitializer對應的類型并實例化
		// 并將加載的數(shù)據(jù)存儲在了 initializers 成員變量中。
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		// 初始化監(jiān)聽器 并將加載的監(jiān)聽器實例對象存儲在了listeners成員變量中
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		// 反推main方法所在的Class對象 并記錄在了mainApplicationClass對象中
		this.mainApplicationClass = deduceMainApplicationClass();
	}

在本方法中完成了幾個核心操作

1.推斷當前項目的類型

2.加載配置在spring.factories文件中的ApplicationContextInitializer中的類型并實例化后存儲在了initializers中。

3.和2的步驟差不多,完成監(jiān)聽器的初始化操作,并將實例化的監(jiān)聽器對象存儲在了listeners成員變量中

4.通過StackTrace反推main方法所在的Class對象

上面的核心操作具體的實現(xiàn)細節(jié)我們在后面的詳細文章會給大家剖析

4.run方法

接下來我們在回到SpringApplication.run()方法中。

	public ConfigurableApplicationContext run(String... args) {
		// 創(chuàng)建一個任務執(zhí)行觀察器
		StopWatch stopWatch = new StopWatch();
		// 開始執(zhí)行記錄執(zhí)行時間
		stopWatch.start();
		// 聲明 ConfigurableApplicationContext 對象
		ConfigurableApplicationContext context = null;
		// 聲明集合容器用來存儲 SpringBootExceptionReporter 啟動錯誤的回調接口
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		// 設置了一個名為java.awt.headless的系統(tǒng)屬性
		// 其實是想設置該應用程序,即使沒有檢測到顯示器,也允許其啟動.
		//對于服務器來說,是不需要顯示器的,所以要這樣設置.
		configureHeadlessProperty();
		// 獲取 SpringApplicationRunListener 加載的是 EventPublishingRunListener
		// 獲取啟動時到監(jiān)聽器
		SpringApplicationRunListeners listeners = getRunListeners(args);
		// 觸發(fā)啟動事件
		listeners.starting();
		try {
			// 構造一個應用程序的參數(shù)持有類
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			// 創(chuàng)建并配置環(huán)境
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			// 配置需要忽略的BeanInfo信息
			configureIgnoreBeanInfo(environment);
			// 輸出的Banner信息
			Banner printedBanner = printBanner(environment);
			// 創(chuàng)建應用上下文對象
			context = createApplicationContext();
			// 加載配置的啟動異常處理器
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			// 刷新前操作
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			// 刷新應用上下文 完成Spring容器的初始化
			refreshContext(context);
			// 刷新后操作
			afterRefresh(context, applicationArguments);
			// 結束記錄啟動時間
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			// 事件廣播 啟動完成了
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			// 事件廣播啟動出錯了
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			// 監(jiān)聽器運行中
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		// 返回上下文對象--> Spring容器對象
		return context;
	}

在這個方法中完成了SpringBoot項目啟動的很多核心的操作,我們來總結下上面的步驟

  • 創(chuàng)建了一個任務執(zhí)行的觀察器,統(tǒng)計啟動的時間
  • 聲明ConfigurableApplicationContext對象
  • 聲明集合容器來存儲SpringBootExceptionReporter即啟動錯誤的回調接口
  • 設置java.awt.headless的系統(tǒng)屬性
  • 獲取我們之間初始化的監(jiān)聽器(EventPublishingRunListener),并觸發(fā)starting事件
  • 創(chuàng)建ApplicationArguments這是一個應用程序的參數(shù)持有類
  • 創(chuàng)建ConfigurableEnvironment這時一個配置環(huán)境的對象
  • 配置需要忽略的BeanInfo信息
  • 配置Banner信息對象
  • 創(chuàng)建對象的上下文對象
  • 加載配置的啟動異常的回調異常處理器
  • 刷新應用上下文,本質就是完成Spring容器的初始化操作
  • 啟動結束記錄啟動耗時
  • 完成對應的事件廣播
  • 返回應用上下文對象。

到此SpringBoot項目的啟動初始化的代碼的主要流程就介紹完成了。細節(jié)部分后面詳細講解。

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • SpringCloud Eureka 服務注冊實現(xiàn)過程

    SpringCloud Eureka 服務注冊實現(xiàn)過程

    這篇文章主要介紹了SpringCloud Eureka 服務注冊實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Spring Cloud Feign接口返回流的實現(xiàn)

    Spring Cloud Feign接口返回流的實現(xiàn)

    這篇文章主要介紹了Spring Cloud Feign接口返回流的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • 一文帶你玩轉Java異常處理

    一文帶你玩轉Java異常處理

    這篇文章主要為大家介紹一下Java中的異常處理機制,文中通過示例為大家進行了詳細的介紹,對我們學習有一定的幫助,感興趣的可以了解一下
    2022-08-08
  • 在idea環(huán)境下構建springCloud項目

    在idea環(huán)境下構建springCloud項目

    本篇文章主要介紹了在idea環(huán)境下構建springCloud項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 淺談jvm中的垃圾回收策略

    淺談jvm中的垃圾回收策略

    下面小編就為大家?guī)硪黄獪\談jvm中的垃圾回收策略。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 基于SSM框架+Javamail發(fā)送郵件的代碼實例

    基于SSM框架+Javamail發(fā)送郵件的代碼實例

    本篇文章主要介紹了基于SSM框架+Javamail發(fā)送郵件的代碼實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-12-12
  • MAC下如何設置JDK環(huán)境變量

    MAC下如何設置JDK環(huán)境變量

    這篇文章主要介紹了MAC下如何設置JDK環(huán)境變量問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringMVC實現(xiàn)簡單跳轉方法(專題)

    SpringMVC實現(xiàn)簡單跳轉方法(專題)

    這篇文章主要介紹了SpringMVC實現(xiàn)簡單跳轉方法(專題),詳細的介紹了SpringMVC跳轉的幾種方法,非常具有實用價值,需要的朋友可以參考下
    2018-03-03
  • HttpMessageConverter報文信息轉換器的深入講解

    HttpMessageConverter報文信息轉換器的深入講解

    在Spring中內置了大量的HttpMessageConverter,通過請求頭信息中的MIME類型,選擇相應的HttpMessageConverter,這篇文章主要給大家介紹了關于HttpMessageConverter報文信息轉換器的相關資料,需要的朋友可以參考下
    2022-01-01
  • Java實現(xiàn)經典角色扮演偵探游戲游戲的示例代碼

    Java實現(xiàn)經典角色扮演偵探游戲游戲的示例代碼

    這篇文章主要介紹了如何利用Java語言自制一個偵探文字游戲—《角色扮演偵探》,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編學習一下
    2022-02-02

最新評論