SpringBoot配置檔案及自動配置原理詳解,這應該是SpringBoot最大的優勢了吧

Java魚仔發表於2020-10-05

點贊再看,養成習慣,聽說微信搜公眾號《Java魚仔》會讓自己的技術更上一層樓

(一)概述

SpringBoot使用一個全域性的配置檔案來修改SpringBoot自動配置的預設值,SpringBoot提供了三種格式的配置檔案:
在這裡插入圖片描述
如果一個專案中同時有上面三種配置檔案,只會執行application*.yml,同理如果只有yaml和properties,只會執行yaml。

yml和yaml具有相同的格式 key:空格value 注意這個空格不能沒有

server:
  port: 8080

properties的格式為 key=value

server.port=8080

(二)配置檔案從哪來的?

springboot的配置檔案中存在大量的配置,這一點在官網上就能看到了:
https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/common-application-properties.html
如果要用的時候直接去官方文件或者百度取確實是個辦法,但卻並不是最好的辦法,最好的辦法是理解這些配置檔案的原理,以後要用的時候直接通過原理去寫配置檔案。

在前面一章講自動裝配的時候我們已經知道了,Springboot專案在啟動時會去META-INF/spring.factories取配置資訊
在這裡插入圖片描述
配置檔案的源頭也來自於這裡。

我們以Redis的配置類為例子講解配置檔案的原理,點開spring.factories,通過ctrl+F查詢redis,可以找到一個叫RedisAutoConfiguration的類。
在這裡插入圖片描述
點進去後你能見到一個叫@EnableConfigurationProperties的註解,並且他後面會帶上一個叫XXXProperties的類,Redis這裡叫做RedisProperties。XXXProperties是配置檔案的核心。
@EnableConfigurationProperties的意思是讓@ConfigurationProperties 註解的類生效,後面我們就能看到
在這裡插入圖片描述
XXXProperties這個類被@ConfigurationProperties註解,這就和前面的@EnableConfigurationProperties對應上了,@ConfigurationProperties可以將配置檔案(比如applicaition.yaml)載入進來,填充物件的對應欄位的資料,然後供其他Bean使用。這裡需要寫一個字首,在配置檔案中通過"字首.變數"的形式配置相應的值。

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

   /**
    * Database index used by the connection factory.
    */
   private int database = 0;
   /**
    * Connection URL. Overrides host, port, and password. User is ignored. Example:
    * redis://user:password@example.com:6379
    */
   private String url;
   /**
    * Redis server host.
    */
   private String host = "localhost";
   /**
    * Login password of the redis server.
    */
   private String password;
   /**
    * Redis server port.
    */
   private int port = 6379;
   /**
    * Whether to enable SSL support.
    */
   private boolean ssl;
   /**
    * Connection timeout.
    */
   private Duration timeout;
   /**
    * Client name to be set on connections with CLIENT SETNAME.
    */
   private String clientName;
   private Sentinel sentinel;
   private Cluster cluster;
   private final Jedis jedis = new Jedis();
   private final Lettuce lettuce = new Lettuce();
   //。。。。。。。。。。

看到這裡我想你們已經知道配置檔案的原理了,我們平常寫的配置檔案,肯定是為某一個類的變數賦予了值,我們寫配置檔案就可以通過“字首.變數”的形式來寫。
還是以上面的程式碼為例,我們如果想要給redis設定一個地址,“字首.變數”就是spring.redis.host,這個值就會被RedisProperties 獲取到,
在這裡插入圖片描述

(三)配置檔案處理總結

  1. 我們可以在META-INF/spring.factories中找到XXXAutoConfiguration這個自動裝配類
  2. 所有在配置檔案中能配置的屬性都是在xxxxProperties類中封裝著;
  3. 配置檔案能配置什麼就可以參照某個功能對應的這個屬性類

(四)自己寫一個配置類

既然我們知道了springboot是如何取配置檔案的,那麼我們可以自己來寫一個配置類讀取配置。
新建一個package properties,在裡面新建一個類叫做UserProperties。

@Data
@Component
@ConfigurationProperties(prefix = "myproperties.user")
public class UserProperties {
    private String name;
    private Integer age;
}

在使用@ConfigurationProperties的同時必須啟用它,我現在用了@Component讓 Component Scan 掃描到,如果單純寫一個@ConfigurationProperties註解,會提示報錯

Not registered via @EnableConfigurationProperties, marked as Spring component, or scanned via @ConfigurationPropertiesScan

接著在配置檔案中賦值,我這裡用的是application.yaml

myproperties:
  user:
    name: javayz
    age: 23

通過測試方法測試:

@SpringBootTest
class SpringbootdemoApplicationTests {
    @Autowired
    UserProperties userProperties;
    @Test
    void contextLoads() {
        System.out.println(userProperties);
    }
}

在這裡插入圖片描述
除了使用@Component來啟用配置註解外,我們還可以參考原始碼的方式啟用它:原始碼是這樣寫的
在這裡插入圖片描述
現在去除UserProperties的@Component註解,新建一個package config,並新建一個類叫UserConfig

@Configuration
@EnableConfigurationProperties(UserProperties.class)
public class UserConfig {
}

執行測試類後獲得相同的正確結果。這就是閱讀原始碼的好處,通過原始碼學習別人的編碼方式。

(五)結語

如果完整的看完整篇文章,我相信你對SpringBoot的配置檔案以及自動配置的原理有了比較深刻的原理,看原始碼有時候並不難。

相關文章