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

Java?SpringBoot核心源碼詳解

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

SpringBoot源碼主線分析

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

1.SpringBoot啟動(dòng)的入口

當(dāng)我們啟動(dòng)一個(gè)SpringBoot項(xiàng)目的時(shí)候,入口程序就是main方法,而在main方法中就執(zhí)行了一個(gè)run方法。

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

2.run方法

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

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

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

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

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

3.SpringApplication構(gòu)造器

我們進(jìn)入SpringApplication的構(gòu)造方法,看的核心代碼為

	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));
		// 記錄當(dāng)前項(xiàng)目的類型
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		// 加載配置在spring.factories文件中的ApplicationContextInitializer對應(yīng)的類型并實(shí)例化
		// 并將加載的數(shù)據(jù)存儲(chǔ)在了 initializers 成員變量中。
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		// 初始化監(jiān)聽器 并將加載的監(jiān)聽器實(shí)例對象存儲(chǔ)在了listeners成員變量中
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		// 反推main方法所在的Class對象 并記錄在了mainApplicationClass對象中
		this.mainApplicationClass = deduceMainApplicationClass();
	}

在本方法中完成了幾個(gè)核心操作

1.推斷當(dāng)前項(xiàng)目的類型

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

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

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

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

4.run方法

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

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

在這個(gè)方法中完成了SpringBoot項(xiàng)目啟動(dòng)的很多核心的操作,我們來總結(jié)下上面的步驟

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

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

總結(jié)

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

相關(guān)文章

  • SpringBoot yml配置文件調(diào)用過程解析

    SpringBoot yml配置文件調(diào)用過程解析

    這篇文章主要介紹了SpringBoot yml配置文件調(diào)用過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java中SynchronousQueue的底層實(shí)現(xiàn)原理剖析

    Java中SynchronousQueue的底層實(shí)現(xiàn)原理剖析

    BlockingQueue的實(shí)現(xiàn)類中,有一種阻塞隊(duì)列比較特殊,就是SynchronousQueue(同步移交隊(duì)列),隊(duì)列長度為0。本文就來剖析一下SynchronousQueue的底層實(shí)現(xiàn)原理,感興趣的可以了解一下
    2022-11-11
  • Spring?中?PageHelper?不生效問題及解決方法

    Spring?中?PageHelper?不生效問題及解決方法

    這篇文章主要介紹了Spring?中?PageHelper?不生效問題,使用這個(gè)插件時(shí)要注意版本的問題,不同的版本可能 PageHelper 不會(huì)生效,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 詳解java中的深拷貝和淺拷貝(clone()方法的重寫、使用序列化實(shí)現(xiàn)真正的深拷貝)

    詳解java中的深拷貝和淺拷貝(clone()方法的重寫、使用序列化實(shí)現(xiàn)真正的深拷貝)

    這篇文章主要介紹了java中的深拷貝和淺拷貝(clone()方法的重寫、使用序列化實(shí)現(xiàn)真正的深拷貝),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Jmeter邏輯控制器事務(wù)控制器使用方法解析

    Jmeter邏輯控制器事務(wù)控制器使用方法解析

    這篇文章主要介紹了Jmeter邏輯控制器事務(wù)控制器使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Eclipse添加xml文件提示及Hibernate配置學(xué)習(xí)

    Eclipse添加xml文件提示及Hibernate配置學(xué)習(xí)

    文件提示功能在開發(fā)過程中很實(shí)用的,本文實(shí)現(xiàn)了一個(gè)Eclipse添加xml文件提示,感興趣的朋友可以了解下啊,希望本文對你有所幫助
    2013-01-01
  • java爬取豆瓣電影示例解析

    java爬取豆瓣電影示例解析

    這篇文章主要介紹了java爬取豆瓣電影示例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java來實(shí)現(xiàn)文本轉(zhuǎn)圖片需求示例

    Java來實(shí)現(xiàn)文本轉(zhuǎn)圖片需求示例

    本文主要介紹了Java來實(shí)現(xiàn)文本轉(zhuǎn)圖片需求示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Java程序圖形用戶界面設(shè)計(jì)之按鈕與布局

    Java程序圖形用戶界面設(shè)計(jì)之按鈕與布局

    圖形界面(簡稱GUI)是指采用圖形方式顯示的計(jì)算機(jī)操作用戶界面。與早期計(jì)算機(jī)使用的命令行界面相比,圖形界面對于用戶來說在視覺上更易于接受,本篇精講Java語言中關(guān)于圖形用戶界面的按鈕和布局部分
    2022-02-02
  • SpringBoot3.x集成nacos并實(shí)現(xiàn)多環(huán)境配置的操作步驟

    SpringBoot3.x集成nacos并實(shí)現(xiàn)多環(huán)境配置的操作步驟

    本文詳細(xì)介紹了如何在Springboot3.x中集成Nacos2.x版本,包括nacos的安裝、配置更改,以及在集成過程中遇到的問題,如端口設(shè)置、依賴版本調(diào)整等,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10

最新評論

周宁县| 石首市| 大丰市| 福鼎市| 青田县| 赤水市| 贡觉县| 凤冈县| 星座| 兰溪市| 南开区| 稷山县| 运城市| 苍山县| 西昌市| 南漳县| 浮山县| 太保市| 萍乡市| 阳新县| 乐至县| 涞水县| 永州市| 会宁县| 丰都县| 丹寨县| 嘉义市| 伊通| 丹江口市| 宜君县| 永丰县| 芦山县| 车险| 屯门区| 颍上县| 通化县| 砀山县| 平江县| 衡东县| 密山市| 历史|