深入理解SpringBoot(1)

之前學習過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 指定的值,將這些值作爲自動配置類導入容器中,自動配置類就會生效,自動幫我們配置好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章