之前學習過springboot,但是由於很長一段時間沒有用到springboot,想重新學習一遍,決定用一段時間來寫一系列深入學習springboot的博客,將會從一些註解,官方文檔等多個方面來深入理解springboot的運行機制。
首先從pom文件中的parent來開始:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
這是springboot中管理版本的方法,我們進入spring-boot-starter-parent
中看看它的parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
繼續進入 spring-boot-dependencies
可以看到如下的代碼(這裏只截取部分的代碼):
<properties>
<activemq.version>5.15.10</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.76</appengine-sdk.version>
<artemis.version>2.10.1</artemis.version>
<aspectj.version>1.9.4</aspectj.version>
<assertj.version>3.13.2</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
....
<mongodb.version>3.11.1</mongodb.version>
....
....
</properties>
springboot2.2幫我們配置好了,springboot2.2它對應哪些版本,比如說你要用mongodb,只需要在pom中引入它的依賴,不需要指定版本,版本會自動到properties
中幫你匹配好。這是它的實現機制。
我們再看一下Application啓動函數的註解 @SpringBootApplication
,同樣的,我們去它的源碼中去看看:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@ConfigurationPropertiesScan
它相當於爲我們封裝了一大批的註解,我們只需要用這一個註解就實現了這麼多註解的功能,我們再仔細研究一下這些註解都有些什麼功能。
對 @SpringBootConfiguration
這個註解,它同樣也是一個俄羅斯套娃,它也封裝了一系列的註解,包括一些@configuration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration(
proxyBeanMethods = false
)
它是springboot的配置類,標註在某個類上就表示這個類是配置類。和 @Configuration
的作用是差不多的,只不過@Configuration
是spring定義的,而 @SpringBootConfiguration
是springboot定義的,它除此之外比spring定義的更完善(包含其他的一些springboot註解)。它們都是屬於@Component
,可以點開看一下。
再看一下,@EnableAutoConfiguration
,這是開啓自動配置功能,幫我們自動配置。
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
我們繼續看看這個@AutoConfigurationPackage
,它包含下面的這一項:
@Import(AutoConfigurationPackages.Registrar.class)
@import
標籤是屬於 springboot 底層,它表示給容器中導入組件,調用AutoConfigurationPackages.Registrar.class
這個類,這個類中可能包括一些配置的方法等等。
@EnableAutoConfiguration
實際上,它會把SpringBootApplication
標註的類,及所在的包下面的所有子包裏面所有的組件都掃描到spring容器中。
學到這裏,我們可以做一個實驗,下面是我的包結構:
我的啓動類是ReviewApplication,我在com.king.review
下面建立一個子包controller
,接下來在controller下面建立一個類,下面是它的內容:
package com.king.review.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String Hello(){
return "hello world";
}
}
當我們啓動之後,可以正常在本地 http://localhost:8080/hello,訪問到hello world,但是當我們把controller類放在com.king.review
之外,它就不能訪問到了。
我們有了一些自動配置類,就省去了我們手動編寫配置注入功能等組件。
總結: SpringBoot在啓動的時候在類路徑下META-INF/spring.factories獲取@EnableAutoConfiguration
指定的值,將這些值作爲自動配置類導入容器中,自動配置類就會生效,自動幫我們配置好。