SpringBoot自動裝配原理初探

前言

Spring翻譯為中文是“春天”,的確井辆,在某段時間內杯缺,它給Java開發(fā)人員帶來過春天,但是隨著我們項目規(guī)模的擴大袍榆,Spring需要配置的地方就越來越多塘揣,夸張點說,“配置兩小時才写,Coding五分鐘”奖蔓。這種紛繁復雜的xml配置隨著軟件行業(yè)一步步地發(fā)展,必將逐步退出歷史舞臺厨疙。

SpringBoot介紹

來自:百度百科
Spring Boot是由Pivotal團隊提供的全新框架疑务,其設計目的是用來簡化新Spring應用的初始搭建以及開發(fā)過程。該框架使用了特定的方式來進行配置搭独,從而使開發(fā)人員不再需要定義樣板化的配置廊镜。通過這種方式,Spring Boot致力于在蓬勃發(fā)展的快速應用開發(fā)領域(rapid application development)成為領導者配椭。

SpringBoot所具備的特征有:

(1)可以創(chuàng)建獨立的Spring應用程序雹姊,并且基于其Maven或Gradle插件,可以創(chuàng)建可執(zhí)行的JARs和WARs敦姻;

(2)內嵌Tomcat或Jetty等Servlet容器;

(3)提供自動配置的“starter”項目對象模型(POMS)以簡化Maven配置迷守;

(4)盡可能自動配置Spring容器旺入;

(5)提供準備好的特性茵瘾,如指標、健康檢查和外部化配置拗秘;

(6)絕對沒有代碼生成雕旨,不需要XML配置。

自己的理解

SpringBoot餐禁,顧名思義突照,給人的感覺就是讓Spring啟動的這么一個項目。在過去末盔,我們要讓一個Spring項目啟動座慰,往往需要配置很多的xml配置文件,但是在使用SpringBoot之后游盲,我們甚至無需寫一行xml蛮粮,就可以直接將整個項目啟動然想,這種“零配置”的做法減輕了開發(fā)人員很多的工作量,可以讓開發(fā)人員一心撲在業(yè)務邏輯的設計上变泄,使項目的邏輯更加完善。除此之外屏富,其采用了JavaConfig的配置風格役听,導入組件的方式也由原來的直接配置改為@EnableXXXX表窘,這種純Java代碼的配置和導入組件的方式,使代碼看上去更加的優(yōu)雅瘤袖,所以SpringBoot如今受到大小公司和大多數(shù)程序員的青睞昂验,不是沒有原因的。

SpringBoot之所以可以做到簡化配置文件直接啟動占婉,無外乎是其內部的兩種設計策略:開箱即用約定大于配置甫恩。

開箱即用:在開發(fā)過程中磺箕,通過maven項目的pom文件中添加相關依賴包,然后通過相應的注解來代替繁瑣的XML配置以管理對象的生命周期松靡。

約定大于配置:由SpringBoot本身來配置目標結構雕欺,由開發(fā)者在結構中添加信息的軟件設計范式。這一特點雖降低了部分靈活性蛛枚,增加了BUG定位的復雜性脸哀,但減少了開發(fā)人員需要做出決定的數(shù)量,同時減少了大量的XML配置盲镶,并且可以將代碼編譯、測試和打包等工作自動化枫吧。

那么在這篇博客中宇色,我們需要了解的所有東西,就應該從這兩個特點出發(fā)例隆,一步一步深入SpringBoot自動裝配的原理抢蚀。

開箱即用原理

要理解這一特點皿曲,首先要先自己體會開箱即用的整個過程帶來的便利。

  • 體驗開箱即用

    SpringBoot提供了我們快速創(chuàng)建SpringBoot項目的地方:https://start.spring.io/

    我們只需要在這個網(wǎng)頁中把整個項目起好名字坞古,然后選好我們需要的組件劫樟,就可以直接獲得一個可以跑起來的SpringBoot項目。

    官網(wǎng)生成

    我們只需要填完上述信息听怕,點擊Generate虑绵,就可以直接將一個SpringBoot項目下載下來翅睛,然后導入我們的IDE,Eclipse或者IDEA都可疏旨,之后就可以直接將它運行起來扎酷。

    全項目結構:

    全項目結構

    啟動

    項目啟動

    訪問:http://localhost:8080/

    啟動成功

    代表整個SpringBoot項目啟動成功。

  • 開箱即用原理剖析

    • 對比SSM配置

      其實在上文的開箱即用中谁榜,我們相當于引入了一個SpringMVC的組件窃植,但是大家可以看到,我們沒有經(jīng)過任何的配置就將項目啟動了葛超。反觀過去SSM框架的SpringMVC配置延塑,我這里有一份留存的大家可以對比一下。

      spring-web.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/mvc
          http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
          <!-- 配置SpringMVC -->
          <!-- 1.開啟SpringMVC注解模式 -->
          <!-- 簡化配置: (1)自動注冊DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter 
              (2)提供一些列:數(shù)據(jù)綁定胖替,數(shù)字和日期的format @NumberFormat, @DateTimeFormat, xml,json默認讀寫支持 -->
          <mvc:annotation-driven />
      
          <!-- 2.靜態(tài)資源默認servlet配置 (1)加入對靜態(tài)資源的處理:js,gif,png (2)允許使用"/"做整體映射 -->
          <mvc:resources mapping="/resources/**" location="/resources/" />
          <mvc:default-servlet-handler />
      
          <!-- 3.定義視圖解析器 -->
          <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="prefix" value="/WEB-INF/html/"></property>
              <property name="suffix" value=".html"></property>
          </bean>
          <!-- 文件上傳解析器 -->
          <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
              <property name="defaultEncoding" value="utf-8"></property>
              <property name="maxUploadSize" value="10485760000"></property><!-- 最大上傳文件大小 -->
              <property name="maxInMemorySize" value="20971520"></property>
          </bean>
          <!-- 在spring-mvc.xml文件中加入這段配置后,spring返回給頁面的都是utf-8編碼了 -->
          <bean
              class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
              <property name="messageConverters">
                  <list>
                      <bean
                          class="org.springframework.http.converter.StringHttpMessageConverter">
                          <property name="supportedMediaTypes">
                              <list>
                                  <value>text/html;charset=UTF-8</value>
                              </list>
                          </property>
                      </bean>
                  </list>
              </property>
          </bean>
          <!-- 4.掃描web相關的bean -->
          <context:component-scan base-package="com.SchoolShop.o2o.web" />
          <!-- 5.權限攔截器 -->
      </beans>
      

      web.xml:

      <servlet>
          <servlet-name>spring-dispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring/spring-*.xml</param-value>
          </init-param>
        </servlet>
        <servlet-mapping>
          <servlet-name>spring-dispatcher</servlet-name>
          <!-- 默認匹配所有請求 -->
          <url-pattern>/</url-pattern>
        </servlet-mapping>
      

      可以看到键耕,這里需要配置兩個文件,web.xml和spring-web.xml辽慕,配置可以說是相當復雜老速。

      相對于這個乘凸,SpringBoot的開箱即用就顯得特別方便,那么我們著重聊聊SpringBoot開箱即用的原理营勤。

    • 從pom.xml開始

      SpringBoot的項目都會存在一個父依賴葛作,按住Ctrl+鼠標左鍵,可以點進去绪穆。

      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.2.1.RELEASE</version>
          <relativePath/> <!-- lookup parent from repository -->
      </parent>
      

      點進去之后發(fā)現(xiàn)里面除了一些插件和配置文件的格式之外,還存在一個依賴漠吻。

      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-dependencies</artifactId>
          <version>2.2.1.RELEASE</version>
          <relativePath>../../spring-boot-dependencies</relativePath>
      </parent>
      

      于是再點進去司恳,可以發(fā)現(xiàn)里面放了很多的依賴和依賴的版本號。由于這個文件實在太長了耍共,所以這里只展示一部分猎塞。

      父依賴
      父依賴包含

      所以我們可以得出第一個結論

      spring-boot-dependencies:作為父工程荠耽,存放了SpringBoot的核心依賴。我們在寫或者引入一些SpringBoot依賴的時候倘屹,不需要指定版本慢叨,正式因為SpringBoot的父依賴已經(jīng)幫我們維護了一套版本。

      另外我們還可以看到烛缔,在父依賴中也幫我們寫好了資源庫轩拨,不用我們自己再去配置了。

      <resources>
            <resource>
              <filtering>true</filtering>
              <directory>${basedir}/src/main/resources</directory>
              <includes>
                  <!-- 可以讀取的配置文件有
                      application.yml/application.yaml/application.properties
                  -->
                <include>**/application*.yml</include>
                <include>**/application*.yaml</include>
                <include>**/application*.properties</include>
              </includes>
            </resource>
            <resource>
              <directory>${basedir}/src/main/resources</directory>
              <excludes>
                <exclude>**/application*.yml</exclude>
                <exclude>**/application*.yaml</exclude>
                <exclude>**/application*.properties</exclude>
              </excludes>
            </resource>
      </resources>
      
    • 啟動器

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <version>2.2.1.RELEASE</version>
      </dependency>
      

      啟動器就是SpringBoot的啟動場景,比如我們要使用web相關的寸宵,那么就直接引入spring-boot-starter-web,那么他就會幫我們自動導入web環(huán)境下所有必需的依賴梯影。

      我們來看看啟動器中存放了一些什么內容:

      以spring-boot-starter為例:

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.1.RELEASE</version>
            <scope>compile</scope>
          </dependency>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.2.1.RELEASE</version>
            <scope>compile</scope>
          </dependency>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
            <version>2.2.1.RELEASE</version>
            <scope>compile</scope>
          </dependency>
          <dependency>
            <groupId>jakarta.annotation</groupId>
            <artifactId>jakarta.annotation-api</artifactId>
            <version>1.3.5</version>
            <scope>compile</scope>
          </dependency>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
            <scope>compile</scope>
          </dependency>
          <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.25</version>
            <scope>runtime</scope>
          </dependency>
      

      其中存放了自動配置相關的依賴简识、日志相關依賴、還有Spring-core等依賴奢赂,這些依賴我們只需要導入一個spring-boot-starter就可以直接將其全部引入颈走,而不需要再像以前那樣逐個導入了。

      SpringBoot會將所有的功能場景都封裝成一個一個的啟動器轧钓,供開發(fā)人員使用锐膜。

      我們在使用的時候也可以直接去官網(wǎng)上找我們所需的啟動器,直接將其引入。

      獲取啟動器文檔:https://docs.spring.io/spring-boot/docs/2.2.1.RELEASE/reference/html/using-spring-boot.html#using-boot-starter

    • 主程序(重要)

      //@SpringBootApplication 標注媒咳,是一個SpringBoot應用
      @SpringBootApplication
      public class SpringbootdemoApplication {
          public static void main(String[] args) {
              SpringApplication.run(SpringbootdemoApplication.class, args);
          }
      }
      

      在寫SpringBoot項目的時候颅围,總要寫這么一個主程序恨搓,這個主程序最大的特點就是其類上放了一個@SpringBootApplication注解斧抱,這也正是SpringBoot項目啟動的核心,也是我們要研究的重點辉浦。

      注意:之后的分析可能會深入源碼宪郊,源碼是一層一層嵌套的,所以光靠文字說明會比較難以理解懊亡,最好是自己在IDE環(huán)境下跟著一步一步跟著點下去乎串。當然也可以繞過這一部分直接看結論。

      點開@SpringBootApplication鸯两,可以發(fā)現(xiàn)它是一個組合注解,主要是由這么幾個注解構成的忙灼。

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

      我們首先要研究的就是核心的兩個注解 @SpringBootConfiguration@EnableAutoConfiguration钝侠,逐個進行分析。

      1. @SpringBootConfiguration

        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        @Documented
        @Configuration
        public @interface SpringBootConfiguration {
        }
        

        可以看到SpringBootConfiguration其實就攜帶了一個@Configuration注解爬范,這個注解我們再熟悉不過了弱匪,他就代表自己是一個Spring的配置類萧诫。所以我們可以認為:@SpringBootConfiguration = @Configuration

      2. @EnableAutoConfiguration

        顧名思義,這個注解一定和自動配置相關哑诊,點進去看源代碼之后可以發(fā)現(xiàn)及刻,其內部就包含了這么兩個注解。

        @AutoConfigurationPackage //自動配置包
        @Import(AutoConfigurationImportSelector.class)//自動配置導入選擇
        

        來看看@Import(AutoConfigurationImportSelector.class)中的內容:

        它幫我們導入了AutoConfigurationImportSelector暑劝,這個類中存在一個方法可以幫我們獲取所有的配置颗搂,代碼如下。

        /*
          所有的配置都存放在configurations中傅联,
          而這些配置都從getCandidateConfiguration中獲取疚察,
          這個方法是用來獲取候選的配置。
        */
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        
        

        getCandidateConfigurations():

        這個方法可以用來獲取所有候選的配置载碌,那么這些候選的配置又是從哪來的呢?

        /*獲取候選的配置*/
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
             List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
                     getBeanClassLoader());
             Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
                     + "are using a custom packaging, make sure that file is correct.");
             return configurations;
         }
        

        實際上它返回了一個List朗伶,這個List是由loadFactoryNames()方法返回的,其中傳入了一個getSpringFactoriesLoaderFactoryClass()论皆,我們可以看看這個方法的內容猾漫。

        protected Class<?> getSpringFactoriesLoaderFactoryClass() {
         return EnableAutoConfiguration.class;
        }
        

        我們看到了一個眼熟的詞 —— EnableAutoConfiguration,也就是說悯周,它實際上返回的就是標注了這個類的所有包粒督。標注了這個類的包不就是@SpringBootApplication嗎?

        所以我們可以得出結論:它兜兜轉轉饒了這么多地方禽翼,就是為了將啟動類所需的所有資源導入屠橄。

        我們接著往下看,它其中還有這么一條語句闰挡,是一條斷言:

        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
                     + "are using a custom packaging, make sure that file is correct.");
        

        這個斷言的意思是锐墙,configurations必須非空长酗,否則就打印一段話溪北,No auto configuration classes found in META-INF/spring.factories,我們把這個邏輯反過來想想夺脾。如果這個集合不為空之拨,是不是就代表找到了這個spring.factories并且會去加載這個文件中的內容呢?

        帶著這個疑問劳翰,我們首先找到spring.factories這個文件:

        找到核心文件

        可以看到里面包含了很多自動配置屬性:

        文件內容

        我們可以隨便找一個自動配置點進去,比如WebMvcAutoConfiguration

        自動配置類

        這里放了所有關于WebMvc的配置敦锌,如視圖解析器馒疹、國際化等等佳簸。

      分析到這里,我們就可以得出一個完整的結論了:

      當我們的SpringBoot項目啟動的時候颖变,會先導入AutoConfigurationImportSelector生均,這個類會幫我們選擇所有候選的配置,我們需要導入的配置都是SpringBoot幫我們寫好的一個一個的配置類腥刹,那么這些配置類的位置马胧,存在與META-INF/spring.factories文件中,通過這個文件衔峰,Spring可以找到這些配置類的位置佩脊,于是去加載其中的配置蛙粘。

      結論1流程

      看到這里,可能有些同學會存在疑問威彰,spring.factories中存在那么多的配置出牧,每次啟動時都是把它們全量加載嗎?這顯然是不現(xiàn)實的歇盼。

      這其實也是我在看源碼的時候存在疑問的地方舔痕,因為其中有一個注解并不常用,我們點開一個配置類就可以看到豹缀。

      判斷注解

      @ConditionalOnXXX:如果其中的條件都滿足伯复,該類才會生效。

      所以在加載自動配置類的時候邢笙,并不是將spring.factories的配置全量加載進來啸如,而是通過這個注解的判斷,如果注解中的類都存在氮惯,才會進行加載组底。

      所以就實現(xiàn)了:我們在pom.xml文件中加入stater啟動器,SpringBoot自動進行配置筐骇。完成開箱即用债鸡。

    • 結論

      SpringBoot所有自動配置類都是在啟動的時候進行掃描并加載,通過spring.factories可以找到自動配置類的路徑铛纬,但是不是所有存在于spring,factories中的配置都進行加載厌均,而是通過@ConditionalOnClass注解進行判斷條件是否成立(只要導入相應的stater,條件就能成立)告唆,如果條件成立則加載配置類棺弊,否則不加載該配置類。

      在這里貼一個我認為的比較容易理解的過程

      1. SpringBoot在啟動的時候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值

      2. 將這些值作為自動配置類導入容器 擒悬, 自動配置類就生效 模她, 幫我們進行自動配置工作;

      3. 以前我們需要自己配置的東西 懂牧, 自動配置類都幫我們解決了

      4. 整個J2EE的整體解決方案和自動配置都在springboot-autoconfigure的jar包中侈净;

      5. 它將所有需要導入的組件以全類名的方式返回 , 這些組件就會被添加到容器中 僧凤;

      6. 它會給容器中導入非常多的自動配置類 (xxxAutoConfiguration), 就是給容器中導入這個場景需要的所有組件 畜侦, 并配置好這些組件 ;

      7. 有了自動配置類 躯保, 免去了我們手動編寫配置注入功能組件等的工作旋膳;

        摘自https://blog.kuangstudy.com/index.php/archives/630/

      最終結論流程

約定大于配置

開箱即用的原理說完了,約定大于配置就比較好理解了途事。其實約定大于配置就是開箱即用中那些自動配置的細節(jié)验懊。說的具體點就是:我們的配置文件(.yml)應該放在哪個目錄下擅羞,配置文件的命名規(guī)范項目啟動時掃描的Bean义图,組件的默認配置是什么樣的(比如SpringMVC的視圖解析器)等等等等這一系列的東西祟滴,都可以被稱為約定,下面就來一點一點地說一下SpringBoot中的“約定”歌溉。

  • maven目錄結構的約定

    我們可以去Spring的官網(wǎng)查看一下官方文檔垄懂,看看文檔中描述的目錄結構是怎樣的。

    Config locations are searched in reverse order. By default, the configured locations are classpath:/,classpath:/config/,file:./,file:./config/. The resulting search order is the following:

    1. file:./config/
    2. file:./
    3. classpath:/config/
    4. classpath:/

    也就是說痛垛,spring的配置文件目錄可以放在

    1. /config
    2. /(根目錄)
    3. resource/config/
    4. resource/

    這四個路徑從上到下存在優(yōu)先級關系草慧。

  • SpringBoot默認配置文件的約定

    SpringBoot默認可以加載一下三種配置文件:

    1. application.yml
    2. application.yaml
    3. application.properties

    建議使用前兩種作為項目的配置文件。

  • 項目啟動時掃描包范圍的約定

    SpringBoot的注解掃描的默認規(guī)則是SpringBoot的入口類所在包及其子包匙头。

    若入口類所在的包是cn.objectspace.demo那么自動掃描包的范圍是cn.objectspace.demo包及其下面的子包漫谷,如果service包和dao包不在此范圍,則不會自動掃描蹂析。

SpringBoot自動配置類如何讀取yml配置

  • 從更細節(jié)的角度去理解自動配置

    上文中我們闡述了一些SpringBoot自動配置的原理舔示,我們是從全局的角度去看自動配置的整個過程。比如從哪個地方開始進行裝配流程电抚、如何找到裝配的包等惕稻。

    那么現(xiàn)在將自己的視角貼近SpringBoot,來聊聊application.yml中我們配置的東西蝙叛,是如何配置到一個個的配置類中的俺祠。

  • yml配置文件中可以配置那些東西

    首先要知道這個問題的答案,我們應該習慣springboot的配置方式借帘。在上文中我們闡述了SpringBoot總是將所有的配置都用JavaConfig的形式去呈現(xiàn)出來蜘渣,這樣能夠使代碼更加優(yōu)雅。那么yml中配置的東西肺然,必然是要和這種配置模式去進行聯(lián)系的蔫缸,我們在application.yml中配置的東西,通常是一些存在與自動配置類中的屬性际起,那么這些自動配置類拾碌,在啟動的時候是怎么找到的呢?如果你還記得上文的描述加叁,那么你可以很明確地知道:spring.factories倦沧!沒錯,就是它它匕,所以這個問題我們似乎得到了答案——只要存在與spring.factories中的,我們都可以在application.yml中進行配置窖认。當然豫柬,這并不意味著不存在其中的我們就不能配置告希,這些配置類我們是可以進行自定義的,只要我們寫了配置類烧给,我們就可以在yml中配置我們需要的屬性值燕偶,然后在配置類中直接讀取這個配置文件,將其映射到配置類的屬性上础嫡。那么就牽扯出我們的問題了:配置類是如何去讀取yml配置文件中的信息的呢指么?

  • @ConfigurationProperties

    要明白這個問題。我們就首先要去了解這個注解有什么作用榴鼎。

    我們可以自己嘗試在application.yml中去定義一些屬性伯诬,如下:

    object: 
      name: Object
      blogurl: blog.objectspace.cn
    

    我們現(xiàn)在自己定義一個類去讀取這個文件:

    @Component
    @ConfigurationProperties(prefix = "object")
    public class TestConfig {
      private String name;
      private String blogUrl;
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public String getBlogUrl() {
          return blogUrl;
      }
      public void setBlogUrl(String blogUrl) {
          this.blogUrl = blogUrl;
      }
    }
    

    然后我們在測試類中輸出一下這個對象:

    @SpringBootTest
    class SpringbootdemoApplicationTests {
      @Autowired
      TestConfig testConfig;
      @Test
      void contextLoads() {
          System.out.println(testConfig.getName());
          System.out.println(testConfig.getBlogUrl());
      }
    
    }
    

    測試結果:

    配置注入

    我們可以看到,在控制臺中輸出了我們在yml中配置的屬性值巫财,但是這些值我們沒有在任何地方顯式地對這個對象進行注入盗似。

    所以@ConfigurationProperties這個注解,可以將yml文件中寫好的值注入到我們類的屬性中平项。

    明白了它的作用赫舒,就能明白自動配置類工作的原理了

    我們依舊是選取SpringMVC的自動配置類闽瓢,我們來看看其中有些什么東西接癌。

    mvcproperties

    點擊任意一個*Properties類中,look一下其中的內容:

    mvc配置注入

    看到這里相信所有人都明白了扣讼,我們就拿mvc配置來舉例扔涧。

    yml演示

    我們在yml中配置的date-format,就可以通過@ConfigurationProperties映射到類中的dateFormat中,然后在通過自動配置類,將這些屬性配置到配置類中届谈。

結語

歡迎大家訪問我的個人博客:Object's Blog

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末枯夜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子艰山,更是在濱河造成了極大的恐慌湖雹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曙搬,死亡現(xiàn)場離奇詭異摔吏,居然都是意外死亡,警方通過查閱死者的電腦和手機纵装,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門征讲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人橡娄,你說我怎么就攤上這事诗箍。” “怎么了挽唉?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵滤祖,是天一觀的道長筷狼。 經(jīng)常有香客問我,道長匠童,這世上最難降的妖魔是什么埂材? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮汤求,結果婚禮上俏险,老公的妹妹穿的比我還像新娘。我一直安慰自己扬绪,他們只是感情好竖独,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勒奇,像睡著了一般预鬓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赊颠,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天格二,我揣著相機與錄音,去河邊找鬼竣蹦。 笑死顶猜,一個胖子當著我的面吹牛,可吹牛的內容都是我干的痘括。 我是一名探鬼主播长窄,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纲菌!你這毒婦竟也來了挠日?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤翰舌,失蹤者是張志新(化名)和其女友劉穎嚣潜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椅贱,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡懂算,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了庇麦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片计技。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖山橄,靈堂內的尸體忽然破棺而出垮媒,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布涣澡,位于F島的核電站贱呐,受9級特大地震影響丧诺,放射性物質發(fā)生泄漏入桂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一驳阎、第九天 我趴在偏房一處隱蔽的房頂上張望抗愁。 院中可真熱鬧,春花似錦呵晚、人聲如沸蜘腌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撮珠。三九已至,卻和暖如春金矛,著一層夾襖步出監(jiān)牢的瞬間芯急,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工驶俊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留娶耍,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓饼酿,卻偏偏與公主長得像榕酒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子故俐,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容