SpringBoot 源碼解析 (一)----- SpringBoot核心原理入門

目錄

Spring Boot 概述什么是 Spring Boot使用 Spring Boot 有什么好處

Spring Boot HelloWorld導(dǎo)入依賴spring boot相關(guān)的依賴編寫主程序編寫Controller、Service運(yùn)行主程序測試

Hello World探究POM文件啟動(dòng)器主程序類(主入口類)

正文

回到頂部

Spring Boot 概述

Build Anything with Spring Boot:Spring Boot is the starting point for building all Spring-based applications. Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring.

上面是引自官網(wǎng)的一段話,大概是說: Spring Boot 是所有基于 Spring 開發(fā)的項(xiàng)目的起點(diǎn)。Spring Boot 的設(shè)計(jì)是為了讓你盡可能快的跑起來 Spring 應(yīng)用程序并且盡可能減少你的配置文件。

什么是 Spring Boot

它使用 “習(xí)慣優(yōu)于配置” (項(xiàng)目中存在大量的配置,此外還內(nèi)置一個(gè)習(xí)慣性的配置,讓你無須手動(dòng)配置)的理念讓你的項(xiàng)目快速運(yùn)行起來。

它并不是什么新的框架,而是默認(rèn)配置了很多框架的使用方式,就像 Maven 整合了所有的 jar 包一樣,Spring Boot 整合了所有框架

使用 Spring Boot 有什么好處

回顧我們之前的 SSM 項(xiàng)目,搭建過程還是比較繁瑣的,需要:

1)配置 web.xml,加載 spring 和 spring mvc

2)配置數(shù)據(jù)庫連接、配置日志文件

3)配置家在配置文件的讀取,開啟注解

4)配置mapper文件

.....

而使用 Spring Boot 來開發(fā)項(xiàng)目則只需要非常少的幾個(gè)配置就可以搭建起來一個(gè) Web 項(xiàng)目,并且利用 IDEA 可以自動(dòng)生成生成

劃重點(diǎn):簡單、快速、方便地搭建項(xiàng)目;對(duì)主流開發(fā)框架的無配置集成;極大提高了開發(fā)、部署效率。

回到頂部

Spring Boot HelloWorld

導(dǎo)入依賴spring boot相關(guān)的依賴

<?xml version="1.0"encoding="UTF-8"?>4.0.0cn.chenhaospringboot1.0.0-SNAPSHOTjarspringbootDemo project for Spring Bootorg.springframework.bootspring-boot-starter-parent2.0.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-maven-plugin

編寫主程序

/** *@SpringBootApplication來標(biāo)注一個(gè)主程序類,說明這是一個(gè)SpringBoot應(yīng)用 */@SpringBootApplicationpublicclassHelloWorldMainApplication{publicstaticvoidmain(String[] args) {//Spring應(yīng)用啟動(dòng)SpringApplication.run(HelloWorldMainApplication.class, args); }}

編寫Controller、Service

@RestControllerpublicclassHelloController{@RequestMapping("/hello")publicString hello(){return"Hello world"; }}

運(yùn)行主程序測試

使用maven打包命令將其打包成jar包后,直接使用命令:

java -jar xxx.jar

回到頂部

Hello World探究

POM文件

父項(xiàng)目

org.springframework.bootspring-boot-starter-parent2.0.1.RELEASE

其父項(xiàng)目是

org.springframework.bootspring-boot-dependencies2.0.1.RELEASE../../spring-boot-dependencies

該父項(xiàng)目是真正管理Spring Boot應(yīng)用里面的所有依賴的版本:Spring Boot的版本仲裁中心,所以以后導(dǎo)入的依賴默認(rèn)是不需要版本號(hào)。如下

還有很多版本號(hào)沒有截圖出來

啟動(dòng)器

org.springframework.bootspring-boot-starter-web

??spring-boot-starter?: spring boot場景啟動(dòng)器;幫助導(dǎo)入web模塊正常運(yùn)行所依賴的組件;

? Spring Boot將所有的功能場景抽取出來,做成一個(gè)個(gè)的starter(啟動(dòng)器),只需要在項(xiàng)目中引入這些starter,那么相關(guān)的場景的所有依賴都會(huì)導(dǎo)入進(jìn)項(xiàng)目中。要用什么功能就導(dǎo)入什么場景的啟動(dòng)器。

org.springframework.bootspring-boot-starter-tomcatorg.springframeworkspring-weborg.springframeworkspring-webmvc

添加了 spring-boot-starter-web 依賴,會(huì)自動(dòng)添加 Tomcat 和 Spring MVC 的依賴

spring-boot-starter-web中又引入了spring-boot-starter-tomcat

主程序類(主入口類)

@SpringBootApplicationpublicclassHelloWorldMainApplication{publicstaticvoidmain(String[] args) {//Spring應(yīng)用啟動(dòng)SpringApplication.run(HelloWorldMainApplication.class, args); }}

@SpringBootApplication

Spring Boot應(yīng)用標(biāo)注在某個(gè)類上,說明這個(gè)類是SpringBoot的主配置類,SpringBoot就應(yīng)該運(yùn)行這個(gè)類的main方法來啟動(dòng)SpringBoot應(yīng)用。

注解定義如下:

@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public@interfaceSpringBootApplication {}

@SpringBootConfiguration

Spring Boot的配置類

標(biāo)注在某個(gè)類上,表示這是一個(gè)Spring Boot的配置類

注解定義如下:

@Configurationpublic@interfaceSpringBootConfiguration {}

其實(shí)就是一個(gè)Configuration配置類,意思是HelloWorldMainApplication最終會(huì)被注冊(cè)到Spring容器中

@EnableAutoConfiguration

開啟自動(dòng)配置功能

以前使用Spring需要配置的信息,Spring Boot幫助自動(dòng)配置;

@EnableAutoConfiguration通知SpringBoot開啟自動(dòng)配置功能,這樣自動(dòng)配置才能生效。

注解定義如下:

@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration {}

@AutoConfigurationPackage

自動(dòng)配置包注解

@Import(AutoConfigurationPackages.Registrar.class)public@interfaceAutoConfigurationPackage {}

@Import(AutoConfigurationPackages.Registrar.class):默認(rèn)將主配置類(@SpringBootApplication)所在的包及其子包里面的所有組件掃描到Spring容器中。如下

@Order(Ordered.HIGHEST_PRECEDENCE)staticclassRegistrarimplementsImportBeanDefinitionRegistrar,DeterminableImports{@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadata metadata,

BeanDefinitionRegistry registry){//默認(rèn)將會(huì)掃描@SpringBootApplication標(biāo)注的主配置類所在的包及其子包下所有組件register(registry,newPackageImport(metadata).getPackageName()); }@OverridepublicSetdetermineImports(AnnotationMetadata metadata){returnCollections.singleton(newPackageImport(metadata)); }}

@Import(EnableAutoConfigurationImportSelector.class)

EnableAutoConfigurationImportSelector: 導(dǎo)入哪些組件的選擇器,將所有需要導(dǎo)入的組件以全類名的方式返回,這些組件就會(huì)被添加到容器中。

1//EnableAutoConfigurationImportSelector的父類:AutoConfigurationImportSelector2@Override3publicString[] selectImports(AnnotationMetadata annotationMetadata) {4if(!isEnabled(annotationMetadata)) {5returnNO_IMPORTS;6}7try{8AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader9.loadMetadata(this.beanClassLoader);10AnnotationAttributes attributes = getAttributes(annotationMetadata);11Listconfigurations= getCandidateConfigurations(annotationMetadata, attributes);12configurations= removeDuplicates(configurations);13configurations=sort(configurations, autoConfigurationMetadata);14Set exclusions = getExclusions(annotationMetadata, attributes);15checkExcludedClasses(configurations, exclusions);16configurations.removeAll(exclusions);17configurations= filter(configurations, autoConfigurationMetadata);18fireAutoConfigurationImportEvents(configurations, exclusions);19returnconfigurations.toArray(newString[configurations.size()]);20}21catch(IOException ex) {22thrownewIllegalStateException(ex);23}24}

我們主要看第11行List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);會(huì)給容器中注入眾多的自動(dòng)配置類(xxxAutoConfiguration),就是給容器中導(dǎo)入這個(gè)場景需要的所有組件,并配置好這些組件。我們跟進(jìn)去看看

protectedList getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());//...returnconfigurations;}protected Class getSpringFactoriesLoaderFactoryClass() {returnEnableAutoConfiguration.class;}publicstaticfinalStringFACTORIES_RESOURCE_LOCATION ="META-INF/spring.factories";publicstaticList loadFactoryNames(Class factoryClass, ClassLoader classLoader) {StringfactoryClassName = factoryClass.getName();try{//從類路徑的META-INF/spring.factories中加載所有默認(rèn)的自動(dòng)配置類Enumeration urls = (classLoader !=null? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));List result =newArrayList();while(urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(newUrlResource(url));//獲取EnableAutoConfiguration指定的所有值,也就是EnableAutoConfiguration.class的值StringfactoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); }returnresult; }catch(IOException ex) {thrownewIllegalArgumentException("Unable to load ["+ factoryClass.getName() +"] factories from location ["+ FACTORIES_RESOURCE_LOCATION +"]", ex); }}

SpringBoot啟動(dòng)的時(shí)候從類路徑下的?META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,并將這些值作為自動(dòng)配置類導(dǎo)入到容器中,自動(dòng)配置類就會(huì)生效,最后完成自動(dòng)配置工作。EnableAutoConfiguration默認(rèn)在spring-boot-autoconfigure這個(gè)包中,如下圖

最終有96個(gè)自動(dòng)配置類被加載并注冊(cè)進(jìn)Spring容器中

J2EE的整體整合解決方案和自動(dòng)配置都在spring-boot-autoconfigure-xxx.jar中。在這些自動(dòng)配置類中會(huì)通過@ConditionalOnClass等條件注解判斷是否導(dǎo)入了某些依賴包,從而通過@Bean注冊(cè)相應(yīng)的對(duì)象進(jìn)行自動(dòng)配置。后面我們會(huì)有單獨(dú)文章講自動(dòng)配置的內(nèi)容

轉(zhuǎn)發(fā)關(guān)注小編,私信小編“學(xué)習(xí)”來免費(fèi)拿走吧~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,801評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,223評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,442評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,800評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,996評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,233評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評(píng)論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,702評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容