SpringApplication是Spring Boot驅動應用上下文的引導類。git
1.Spring Boot項目的啓動類有2種寫法:github
寫法一:web
寫法2:spring
若是把寫法2改爲用寫法1的方式,顯示以下:ide
隨機端口通常是單元測試用的。spring-boot
2.SpringApplication與SpringBootApplication的區別;單元測試
@SpringBootApplication 標註當前一些功能測試
SpringApplication :Spring Boot應用的引導spa
先看一下SpringBootApplication的註解:code
這個註解咱們重點關注3個地方,第一個:@ComponentScan,它是Spring Framework 3.1開始引入的,是掃描的做用。
第二個:@EnableAutoConfiguration,激活自動裝配,@Enable模式,都是@Enable開頭的,好比說:
@EnableWebMvc
@EnableTransactionManagement
@EnableAspectJAutoProxy
@EnableAsync
第三個:@SpringBootApplication
等價於@Configuration
->configuration class註解
說他等價的緣由在此:
舉個例子(Spring註解驅動示例):
註解驅動上下文AnnotationConfigApplicationContext
:Spring Framework 3.0開始引入的
3.@Component的「派生性」
@Component
@Service
@Repository
@Controller
@Configuration
@Service、@Repository、@Controller、@Configuration裏面都是@Component,這個叫作Spring的模式註解。
具體的依據能夠去這兒看:https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model
元註解:標註元註解的註解。也就是說@Component是@Service、@Repository、@Controller、@Configuration的元註解,@Document是全部註解的元註解。
模式註解包括@Component,@Service,@Repository,@Controller,@RestController,@configuration等。(@Contrlloer、@Service、@Repository只是邏輯上的區分,對Spring而言,都是bean。物理上都是同樣的,都是bean defination)
這個派生性只有在@Component裏面生效。由於@Componnent和@ComponentScan的成隊性,@ComponentScan去掃描@Component。它的「子」註解都會被掃進去。即凡是被@Component標註的都會被掃描進去。
爲何@Component的會被掃描進去呢?
即處理類:ConfigurationClassParser
掃描類:
ClassPathBeanDefinitionScanner
ClassPathScanningCandidateComponentProvider
掃描以後用parse方法進行解析,
若是使用默認過濾器,Component、Repository、Service、Controller都會被掃進來。
繼續這個方法往下跟:
這個方法的第一行,代表了只過濾component。
這就是爲何他只掃描ComponentScan。
能夠類比一下dubbo的@Service
->2.5.7版本->new AnnotationTypeFilter(Service.class);
@SpringBootApplication等同於@SpringBootConfiguration,等同於@Configuration,等同於@Component,因此他是一個bean,可是因爲註解是不能繼承的,因此叫「派生性」。
所謂@Component的「派生性」等同於註解的「繼承」。
知道了什麼是Spring模式註解和@Component的「派生性」以後,再回到註解驅動的例子:
先看SpringBoot的啓動示例:
再看下String的:
對比能夠看出輸出的結果是同樣的。因此其實,Spring Boot是驅動Spring的一個容器,只不過是誰來驅動的問題。
爲了進一步證實這個觀點,把上面的例子調整爲非web程序:
打印出來的當前Spring應用上下文的類正是等於它:
現象出來以後,咱們看一下這個的本質:
WebApplicationType.NONE
:非web類型
Servlet
不存在
Spring Web應用上下文ConfigurableWebApplicationContext
不存在
spring-boot-starter-web
不存在
spring-boot-starter-webflux
不存在
WebApplicationType.REACTIVE
:Spring WebFlux
DespatcherHandler
spring-boot-starter-webflux
存在
Servlet
不存在
spring-boot-starter-web
不存在
WebApplicationType.SERVLET
:Spring MVC
spring-boot-starter-web
存在
若是2個包都加入,代碼是有優先級的,判斷以後,會選擇Spring MVC
當不加以設置web類型時,它採用推斷:
SpringApplication()
->deduceWebApplicationType()
第一次推斷爲WebApplicationType.SERVLET
,
設置webApplicationType屬性爲WebApplicationType.NONE
,
當設置爲非web類型,他的server容器也不會啓動了,程序就掛掉了。說明web類型會影響上下文。
設置以後,看看那個方法讀調用了他:
因此說Spring Boot只是一層殼,核心仍是Spring Framework。
SpringApplication是Spring Boot驅動應用上下文的引導類。調用run方法的時候,
看到這,再回到一開始spring的那個例子:
和這個例子中的refresh()對應的。因此說,SpringApplication是Spring Boot驅動應用上下文的引導類。
最後看一下官方文檔關於SpringApplicaiton的說明: