欧美国产成人久久精品,中文字幕成人免费视频,国产成人精品一区二区秒拍,亚洲A∨午夜成人片精品网站


學AI,好工作 就找北大青鳥
關注小青 聽課做題,輕松學習
周一至周日
4000-9696-28

你還在用SpringBoot嗎?別人都已經去研究源碼了

來源:北大青鳥總部 2023年01月12日 11:05

摘要: SpringBoot是怎么做到的約定的配置?它配置在了哪里?來一起跟隨源碼探究下SpringBoot到底是如何做到"約定優于配置"的。

我們都知道SpringBoot自問世以來,一直有一個響亮的口號"約定優于配置",其實一種按約定編程的軟件設計范式,目的在于減少軟件開發人員在工作中的各種繁瑣的配置,我們都知道傳統的SSM框架的組合,會伴隨著大量的繁瑣的配置;稍有不慎,就可能各種bug,被人發現還以為我們技術很菜。而SpringBoot的出現不僅大大提高的開發人員的效率,還能避免由于"手抖"帶來的配置錯誤。


很多程序員都感慨SpringBoot的到來大大解放了生產力,但是也有聰明的程序猿會多思考一下下,SpringBoot是怎么做到的約定的配置?它配置在了哪里?又是怎么啟動的作用等等一系列的問號在跟女朋友花前月下的時候,依然會是不是冒出來。這嚴重影響了程序猿們的"幸"福生活,為了能廣大"程序猿"同胞過上幸福美滿的生活,今天咱么就來一起跟隨源碼探究下SpringBoot到底是如何做到"約定優于配置"的。

首先,我們先介紹下我們的演示的項目環境,我們先試用Spring Initializr來創建一個SpirngBoot工程。我們使用的版本是SpringBoot 2.1.5.RELEASE。



接下來就只在pom.xml文件中添加一個web工程的依賴,是為了觀察后面容器類型的源碼。

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

這樣我們的環境就準備好了。

我們跟著SpringBoot的源碼來探究它的啟動流程,首先,先找到這個應用程序的入口主方法,在上面打一個斷點



啟動之后,F5進入到run()方法

public static ConfigurableApplicationContext run(Class<?>[] primarySources,String[] args) {
return new SpringApplication(primarySources).run(args);
}

到這里會執行new SpringApplication(primarySources)創建spring應用對象,繼續F5往下跟會執行SpringApplication構造器

// SpringApplication構造器
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 資源加載器
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 1. 可能的web應用程序類型的類型。
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 2. 設置初始化應用context
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// 3.設置初始化監聽
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 4. 推演主程序類
this.mainApplicationClass = deduceMainApplicationClass();
}

很多不為人知的事情都是發生在這個對象初始化的時候,這里我們都來一一解密

static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
// 這里是我們測試web容器
return WebApplicationType.SERVLET;
}


一、推斷web應用類型

這段代碼是來推斷我們的應用是哪種web應用程序

public enum WebApplicationType {

/**
* The application should not run as a web application and should not start an
* embedded web server.
*/
NONE, // 不是web應用

/**
* The application should run as a servlet-based web application and should start an
* embedded servlet web server.
*/
SERVLET, // servlet容器

/**
* The application should run as a reactive web application and should start an
* embedded reactive web server.
*/
REACTIVE; // 反應型web應用(webflux)

當然一開始我們加入了web的依賴,所以我們是servlet容器,


二、初始化應用上下文

在設置初始化應用context的時候 ,是先執行了`getSpringFactoriesInstances(ApplicationContextInitializer.class)方法,參數是ApplicationContextInitializer.class字節碼對象

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
// 加載ApplicationContextInitializer.class類型的類
// 這里傳入就是參數 ApplicationContextInitializer.clas
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 實例化加載到的類
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
// 返回
return instances;
}

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

我們先來看看他是如何加載到這些類

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
// 先從緩存中拿
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
// 去資源路徑下加載
public static final String ACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION); result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
// 返回所有的加載的類
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}

這里有兩個加載配置類的地方其實都指向了META-INF/spring.factories,通過斷點我們可以看到應用程序是加載了以下幾個jar下的spring.factores文件。

雙擊Shift搜索spring.factories可以看到它存在于以下工程中



spring-boot-2.1.5.RELEASE.jar下的spring.factores(截圖未完整截取)



spring-boot-autoconfigure-2.1.5.RELEASE.jar下的spring.factores



spring-beans-5.1.7.RELEASE.jar下的spring.factores



從Map中根據org.springframework.context.ApplicationContextInitializer的類型拿到需要的類初始化類,斷點進入getOrDefault(factoryClassName, Collections.emptyList());方法



之后就是把加載到的需要初始化的類進行實例化添加到一個集合中等待備用

public void setInitializers(
Collection<? extends ApplicationContextInitializer<?>> initializers) {
this.initializers = new ArrayList<>();
this.initializers.addAll(initializers);
}


三、初始化監聽器類

最關鍵的的還是這句



當我們跟進去之后,會發現在初始化監聽類的時候和上面初始化應用上下文是一樣的代碼。唯一不同的是getSpringFactoriesInstances(ApplicationListener.class))傳進去的是·ApplicationListener.class所以這里就不再贅述。


四、推演主程序類

也就是這個最關鍵的代碼了

this.mainApplicationClass = deduceMainApplicationClass();




到這里就完成了SpringBoot啟動過程中初始化SpringApplication的過程。


小結

這篇文章主要是給大家說了下SpringBoot啟動過程中初始化SpringApplication的流程,大致可以分為四個步驟:

推演web應用的類型(如果沒有加web依賴類型NONE)

初始化ApplicationContextInitializer

初始化ApplicationListener

推演出主程序類

通過這樣四個步驟就完成了第一步SpringApplication的初始化過程。


標簽: springboot
熱門班型時間
人工智能就業班 即將爆滿
AI應用線上班 即將爆滿
UI設計全能班 即將爆滿
數據分析綜合班 即將爆滿
軟件開發全能班 爆滿開班
網絡安全運營班 爆滿開班
報名優惠
免費試聽
課程資料
官方微信
返回頂部
培訓課程 熱門話題 站內鏈接
欧美国产成人久久精品,中文字幕成人免费视频,国产成人精品一区二区秒拍,亚洲A∨午夜成人片精品网站
  • <span id="i8q4c"></span>

  • <center id="i8q4c"><optgroup id="i8q4c"></optgroup></center>

    • 福利一区二区在线| 天堂资源在线中文精品 | 国产精品一区免费在线观看| 麻豆精品新av中文字幕| 国产电影精品久久禁18| 日日夜夜一区二区| 国产风韵犹存在线视精品| 91免费在线播放| 国产精品一二三四| 蜜桃久久久久久久| 成人av影院在线| 狠狠色综合播放一区二区| 99国产一区二区三精品乱码| 黄一区二区三区| 爽好久久久欧美精品| 国产真实乱对白精彩久久| 91丨九色丨蝌蚪富婆spa| 国产一区二区三区香蕉 | 91免费视频网址| 国产福利不卡视频| 久久国产婷婷国产香蕉| 视频一区二区三区中文字幕| 福利91精品一区二区三区| 精品一区在线看| 奇米影视一区二区三区小说| av一区二区久久| 国产成人自拍在线| 国产一区二区视频在线| 麻豆成人在线观看| 日韩电影网1区2区| 91小视频在线| 99国产精品久久久久久久久久 | 国产一区二三区好的| 免费一级片91| 日韩成人一级片| 99久久婷婷国产综合精品电影| 国产福利一区二区三区| 国产成人久久精品77777最新版本| 久久精品国产网站| 久久综合综合久久综合| 麻豆国产91在线播放| 蜜桃视频在线一区| 麻豆视频观看网址久久| 美女www一区二区| 奇米色一区二区三区四区| 日本va欧美va精品| 久久精品国产久精国产| 久久电影网电视剧免费观看| 久久草av在线| 国产精品1区2区| 国产.欧美.日韩| 成人黄色a**站在线观看| 成人午夜私人影院| 91视频91自| 蜜臀av性久久久久蜜臀aⅴ流畅 | 精品综合久久久久久8888| 久久99精品国产.久久久久久| 久久国产精品第一页| 久久99精品国产麻豆婷婷| 国产一区二区视频在线播放| 国产精品综合在线视频| 丁香婷婷深情五月亚洲| 91丝袜高跟美女视频| 美女爽到高潮91| 国产精品一区三区| 99久久精品国产观看| 日本视频一区二区三区| 极品少妇一区二区| 成人激情黄色小说| 91日韩精品一区| 久久成人免费电影| 本田岬高潮一区二区三区| 日韩电影在线观看一区| 国内精品自线一区二区三区视频| 国产91在线看| 日本va欧美va精品| 成人久久久精品乱码一区二区三区| 91美女视频网站| 国产在线乱码一区二区三区| 成a人片亚洲日本久久| 蜜臂av日日欢夜夜爽一区| 国产99久久久国产精品潘金| 日韩激情视频在线观看| 国产精品亚洲第一| 全国精品久久少妇| 成年人网站91| 国产一区不卡在线| 日本欧美加勒比视频| 国产成a人无v码亚洲福利| 日韩不卡在线观看日韩不卡视频| 国产精品亚洲а∨天堂免在线| 日韩精品一区第一页| 国产suv精品一区二区三区| 奇米一区二区三区| 97久久超碰国产精品电影| 国产精品自拍三区| 蜜桃视频第一区免费观看| 99久久久无码国产精品| 韩国成人在线视频| 琪琪一区二区三区| 91美女福利视频| 国产91在线观看| 国内精品久久久久影院薰衣草 | 国产一区二区看久久| 日韩高清在线一区| av在线一区二区| 成人涩涩免费视频| 国产成人午夜精品影院观看视频 | 麻豆成人久久精品二区三区红 | 97精品久久久午夜一区二区三区 | 成人深夜福利app| 国产很黄免费观看久久| 国内成人自拍视频| 久久99精品国产| 美女免费视频一区二区| 人妖欧美一区二区| 日韩电影一区二区三区四区| 91麻豆精品在线观看| 99精品视频中文字幕| 成年人网站91| av日韩在线网站| jlzzjlzz国产精品久久| 国产91丝袜在线播放九色| 国产精品456露脸| 国产成人在线视频网址| 国产东北露脸精品视频| 国产999精品久久久久久绿帽| 国产成人在线观看免费网站| 国产成人亚洲综合a∨婷婷| 国产成人在线网站| 成人美女视频在线观看18| 国产.欧美.日韩| 不卡在线观看av| 99亚偷拍自图区亚洲| 97精品久久久久中文字幕| 97久久精品人人澡人人爽| 91丨九色丨黑人外教| 国内精品伊人久久久久av影院| 日本 国产 欧美色综合| 久久国产精品99久久人人澡| 国模大尺度一区二区三区| 国产精品1区2区| 波多野结衣91| 奇米色一区二区| 国产一区二区免费视频| 丰满少妇久久久久久久| 99久久伊人精品| 蜜臀国产一区二区三区在线播放| 美女任你摸久久| 国产精一区二区三区| 成人不卡免费av| 爽好久久久欧美精品| 久久91精品久久久久久秒播| 国产福利91精品一区| 99综合电影在线视频| 蜜桃av一区二区| 国产精品一级二级三级| heyzo一本久久综合| 久久综合综合久久综合| 国产ts人妖一区二区| 91蝌蚪porny成人天涯| 精品午夜一区二区三区在线观看| 粉嫩一区二区三区在线看| 91蝌蚪porny| 国产久卡久卡久卡久卡视频精品| 不卡的av网站| 国产一区二区在线看| 91性感美女视频| 国产成人免费网站| 美女尤物国产一区| 99免费精品视频| 国产专区欧美精品| 日本不卡一二三区黄网| 国产99久久久久| 久久99精品久久久久久| 91免费看视频| 成人美女视频在线观看| 精品在线播放免费| 91色在线porny| 国产成人av资源| 韩国成人精品a∨在线观看| 91丝袜美腿高跟国产极品老师 | 国产福利电影一区二区三区| 秋霞午夜鲁丝一区二区老狼| 成人久久久精品乱码一区二区三区| 久久66热re国产| 日韩极品在线观看| av中文字幕一区| 国产成人免费视频精品含羞草妖精| 免费国产亚洲视频| 91亚洲国产成人精品一区二区三| 丰满白嫩尤物一区二区| 国内成人精品2018免费看| 日韩av中文字幕一区二区三区| 国产aⅴ精品一区二区三区色成熟| 久草在线在线精品观看| 免费久久精品视频| 日韩精品电影在线观看| 99国产精品久久久| 99re6这里只有精品视频在线观看| 国产成人午夜电影网| 国产一区二区在线观看免费 | av中文一区二区三区| 国产91精品露脸国语对白| 国产精品香蕉一区二区三区| 久久99日本精品| 精品亚洲欧美一区| 久草热8精品视频在线观看| 另类成人小视频在线| 日本免费新一区视频| 日本欧美一区二区三区乱码| 日韩电影免费在线看| 日本成人超碰在线观看| 免费在线观看日韩欧美| 另类的小说在线视频另类成人小视频在线| 日韩高清在线观看| 老鸭窝一区二区久久精品| 另类小说视频一区二区| 精品午夜久久福利影院| 国产麻豆91精品| 国产成人精品一区二区三区四区 | 粉嫩av一区二区三区在线播放| 国产一区二三区| 国产suv一区二区三区88区| 成人白浆超碰人人人人| 99re热这里只有精品视频| 三级在线观看一区二区| 蜜臀av性久久久久蜜臀aⅴ四虎| 久久99精品久久久久婷婷| 国产高清不卡一区| 99久久免费精品高清特色大片| 日本欧美一区二区在线观看| 精品系列免费在线观看| 丁香亚洲综合激情啪啪综合| 蜜桃91丨九色丨蝌蚪91桃色| 韩国成人福利片在线播放| 国产 欧美在线| 天堂va蜜桃一区二区三区| 久久精品国产一区二区| 国产黄色精品网站| 日韩精品成人一区二区三区| 韩国三级电影一区二区| 成人国产亚洲欧美成人综合网| 91麻豆精品视频| 狠狠色丁香婷婷综合| 成人教育av在线| 免费人成在线不卡| 成人教育av在线| 美女任你摸久久| 成人一区二区在线观看| 男人的j进女人的j一区| 高清免费成人av| 日韩二区在线观看| 国产不卡免费视频| 麻豆精品国产传媒mv男同| 不卡av免费在线观看| 久草这里只有精品视频| 91丨porny丨蝌蚪视频| 国产在线精品一区二区夜色| 成人av综合在线| 国产在线视频一区二区| 日韩精品三区四区| 成人av电影在线| 国产激情视频一区二区在线观看 | 国产成人精品午夜视频免费| 日韩精品91亚洲二区在线观看| 国产成人精品免费一区二区| 日韩不卡一区二区| eeuss鲁片一区二区三区在线观看| 国内精品伊人久久久久av影院 | 日韩制服丝袜先锋影音| 国产精品香蕉一区二区三区| 久久精品久久精品| 日本欧美一区二区三区| 99精品国产一区二区三区不卡| 国产精品一区二区三区网站| 美女高潮久久久| 日本91福利区| 丝袜美腿高跟呻吟高潮一区| 成人一区二区视频| 国产91高潮流白浆在线麻豆| 国产精品资源在线观看| 乱一区二区av| 久久99这里只有精品| 久久精品国产亚洲a| 免费高清视频精品| 青青草国产精品97视觉盛宴| 视频在线在亚洲| 石原莉奈一区二区三区在线观看 | 爽好多水快深点欧美视频| 波多野洁衣一区| av日韩在线网站| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 青青青伊人色综合久久| 91麻豆免费看片| 日韩av电影一区| 免费不卡在线观看| 美女精品一区二区| 九九国产精品视频| 国产一区二区三区在线观看免费| 狠狠色丁香久久婷婷综合_中| 久草这里只有精品视频| 国产在线精品一区二区不卡了| 国产一区二区导航在线播放| 国产麻豆成人传媒免费观看| 国产91丝袜在线18| av午夜精品一区二区三区| 91麻豆免费在线观看| 青青草一区二区三区| 久久99久久久欧美国产| 国产又黄又大久久| 成人午夜在线免费| 91免费版在线| 极品美女销魂一区二区三区免费| 国产曰批免费观看久久久| 国产成人免费视频精品含羞草妖精| 懂色av中文字幕一区二区三区 | 成人av电影在线播放| 97久久精品人人做人人爽| 免费观看成人av| 国产精品123| 99视频超级精品| 免费精品视频在线| 国产成人免费视频网站高清观看视频 | 狠狠色丁香久久婷婷综| 国产.精品.日韩.另类.中文.在线.播放| 成人国产在线观看| 人人爽香蕉精品| 国产成人免费视频一区| 91日韩精品一区| 国产精品影视在线观看| 99re免费视频精品全部| 激情欧美一区二区三区在线观看| 成人18精品视频| 久久超碰97中文字幕| 不卡av在线网| 久久66热re国产| 99re热视频这里只精品| 国产一区二区在线观看视频| 久久99久久久久| 99精品桃花视频在线观看| 黑人巨大精品欧美一区| 91麻豆免费观看| 国产盗摄精品一区二区三区在线| 日韩福利电影在线观看| 成人激情黄色小说| 激情久久久久久久久久久久久久久久| 91在线视频官网| 国产黄人亚洲片| 精品在线观看免费| 日韩高清在线观看| 99视频一区二区三区| 国产一区不卡精品| 美腿丝袜亚洲一区| 丝袜美腿成人在线| zzijzzij亚洲日本少妇熟睡| 国产资源精品在线观看| 免费亚洲电影在线| 丝袜美腿亚洲综合| 9人人澡人人爽人人精品| 国产激情一区二区三区桃花岛亚洲| 美女视频黄a大片欧美| 91丨九色丨黑人外教| 成人sese在线| 粉嫩av一区二区三区在线播放| 国产专区综合网| 久久99热这里只有精品| 蜜臀久久99精品久久久久宅男| 91网上在线视频| 99久久久国产精品| 成人18精品视频| a级精品国产片在线观看| 国产超碰在线一区| 国产不卡高清在线观看视频| 国产经典欧美精品| 国产福利一区在线观看| 国产精品99久久久久| 国产精品白丝av| 国产丶欧美丶日本不卡视频| 国产乱国产乱300精品| 国产精品中文字幕日韩精品| 国产一区二区在线免费观看| 黄一区二区三区| 国产精品自拍三区| 国产不卡视频在线播放| 粉嫩一区二区三区在线看| 丁香天五香天堂综合| 成人黄色777网| 99视频一区二区| 日日夜夜一区二区| 蜜臀av在线播放一区二区三区| 久久精品999| 国产一区三区三区| 国产69精品久久99不卡| 成人av资源在线观看| 视频一区中文字幕| 久久电影国产免费久久电影| 国产九色精品成人porny| 成人精品国产免费网站| 视频在线在亚洲|