一、Springboot是什么
1、springboot是一種服務(wù)于框架(spring)的框架,以“約定優(yōu)于配置”的理念去簡(jiǎn)化項(xiàng)目的搭建和開發(fā),它的服務(wù)范圍是簡(jiǎn)化配置文件。
二、約定優(yōu)于配置指的是什么
????????“約定優(yōu)于配置”指的是大家都以事先定好的規(guī)則去開發(fā),好比:條條大路通羅馬,大家可以走不同的路線,但是這樣會(huì)造成,當(dāng)大家進(jìn)行合作的時(shí)候,無從下手。而事先約定好大家一起走固定的一條路線,這樣便于合作。
????????“約定優(yōu)于配置”具體體現(xiàn)在:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1、maven的目錄結(jié)構(gòu)都是固定的(默認(rèn)以jar的方式打包/默認(rèn)會(huì)有resource文件夾);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2、spring-boot-starter-web等,提供開箱即用的內(nèi)置組件(內(nèi)置tomcat、resource/{template/static});
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3、默認(rèn)使用application.properties等配置文件
三、@SpringBootApplication由哪幾個(gè)注解組成,這幾個(gè)注解分別表示什么作用
? ??????@SpringBootApplication是一個(gè)復(fù)合注解。它包括幾個(gè)部分:
1、@Target
2、@Retention
3、@Documented
4、@Inherited
5、@SpringBootConfiguration
6、@EnableAutoConfiguration
7、@ComponentScan
其中,@Target、@Retention、@Documented、@Inherited是屬于java的元注解(用于注解【注釋】的注解就稱為元注解),他們四個(gè)主要描述作用范圍,生命周期等信息。
所以本質(zhì)上,@SpringBootApplication主要由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三個(gè)注解組成。
1、@SpringBootConfiguration(本質(zhì)上就是@Configuration注解):任何一個(gè)標(biāo)注了@Configuration 的 Java 類定義都是一個(gè)JavaConfig 配置類。而在這個(gè)配置類中,任何標(biāo)注了@Bean 的方法,它的返回值都會(huì)作為 Bean 定義注冊(cè)到Spring 的 IOC 容器,方法名默認(rèn)成為這個(gè) bean 的 id;
2、@EnableAutoConfiguration:EnableAutoConfiguration 的 主 要 作 用 其 實(shí) 就 是 幫 助springboot 應(yīng)用把所有符合條件的@Configuration 配置都加載到當(dāng)前 SpringBoot 創(chuàng)建并使用的 IOC 容器中
3、@ComponentScan:@ComponentScan的主要作用就是掃描指定路徑下的標(biāo)識(shí)了注解需要裝配的類,自動(dòng)裝配到 spring 的 IOC容器中。
四、springboot自動(dòng)裝配的實(shí)現(xiàn)原理
1.SpringApplication.run(StudyApplication.class, args);在run方法中必須要傳入一個(gè)被@SpringBootApplication注解的類。而@SpringBootApplication是一個(gè)復(fù)合注解,其中有@EnableAutoConfiguration注解,

這個(gè)注解下面,有@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)

先看看@AutoConfigurationPackage注解:這個(gè)注解是自動(dòng)配置包,主要是使用的@Import來給Spring容器中導(dǎo)入一個(gè)組件 ,這里導(dǎo)入的是Registrar.class。來看下這個(gè)Registrar:就是通過這個(gè)方法獲取掃描的包路徑,可以debug看看:在這行代碼上打了一個(gè)斷點(diǎn):

啟動(dòng)項(xiàng)目:
進(jìn)入斷點(diǎn)處:

看看能否獲取掃描的包路徑:已經(jīng)獲取到了包路徑:

那那個(gè)metadata是什么呢:
可以看到是標(biāo)注在@SpringBootApplication注解上的DemosbApplication,也就是我們的主配置類:

說白了就是將主配置類(即@SpringBootApplication標(biāo)注的類)的所在包及子包里面所有組件掃描加載到Spring容器。所以包名一定要注意。
現(xiàn)在包掃描路徑獲取到了,那具體加載哪些組件呢,看看下面這個(gè)注解
@Import({AutoConfigurationImportSelector.class})
@Import注解就是給Spring容器中導(dǎo)入一些組件,這里傳入了一個(gè)組件的選擇器:AutoConfigurationImportSelector。里面有一個(gè)selectImports方法,將所有需要導(dǎo)入的組件以全類名的方式返回;這些組件就會(huì)被添加到容器中。
給容器中導(dǎo)入非常多的自動(dòng)配置類(xxxAutoConfiguration);就是給容器中導(dǎo)入這個(gè)場(chǎng)景需要的所有組件,并配置好這些組件:有了自動(dòng)配置類,免去了我們手動(dòng)編寫配置注入功能組件等的工作。
那他是如何獲取到這些配置類的呢,看看上面這個(gè)方法:

會(huì)從META-INF/spring.factories中獲取資源,然后通過Properties加載資源:Spring Boot在啟動(dòng)的時(shí)候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,將這些值作為自動(dòng)配置類導(dǎo)入到容器中,自動(dòng)配置類就生效,幫我們進(jìn)行自動(dòng)配置工作。以前我們需要自己配置的東西,自動(dòng)配置類都幫我們完成了
五、spring中的spi機(jī)制的原理是什么?
service provider interface JDK內(nèi)置的中服務(wù)發(fā)現(xiàn)機(jī)制。
我們知道在SprngBoot中好多的配置和實(shí)現(xiàn)都有默認(rèn)的實(shí)現(xiàn),我們只需要修改部分配置,比如數(shù)據(jù)庫(kù)配置,我們只要在配置文件中寫上對(duì)應(yīng)的url,username,password就可以使用了。其實(shí)他這邊用的就是SPI的方式實(shí)現(xiàn)的,不過Spring使用的只是和JDK中的原理相同而已。
JDK使用的工具類是ServiceLoader;Spring中使用的類是SpringFactoriesLoader,在org.springframework.core.io.support包中
區(qū)別:
1、文件路徑不同 spring配置放在 META-INF/spring.factories中
2、具體的實(shí)現(xiàn)步驟不一樣,不過原理相同,都是使用的反射機(jī)制
服務(wù)的提供者,提供了服務(wù)接口的一種實(shí)現(xiàn)之后,在jar包的META-INF/services/目錄里同時(shí)創(chuàng)建一個(gè)以服務(wù)接口命名的文件。該文件里就是實(shí)現(xiàn)該服務(wù)接口的具體實(shí)現(xiàn)類。而當(dāng)外部程序裝配這個(gè)模塊的時(shí)候,就能通過該jar包META-INF/services/里的配置文件找到具體的實(shí)現(xiàn)類名,并裝載實(shí)例化,完成模塊的注入。通過這個(gè)約定,就不需要把服務(wù)放在代碼中了,通過模塊被裝配的時(shí)候就可以發(fā)現(xiàn)服務(wù)類了。