1. 程式人生 > >SpringBoot基本配置詳解

SpringBoot基本配置詳解

SpringBoot專案有一些基本的配置,比如啟動圖案(banner),比如預設配置檔案application.properties,以及相關的預設配置項。

示例專案程式碼在:https://github.com/laolunsi/spring-boot-examples


一、啟動圖案banner

編寫banner.txt放入resources資料夾下,然後啟動專案即可修改預設圖案。

關於banner的生成,可以去一些專門的網站。

比如:https://www.bootschool.net/ascii


二、配置檔案application

2.1 application.properties/yml

resources下通常會預設生成一個application.properties檔案,這個檔案包含了SpringBoot專案的全域性配置檔案。裡面的配置項通常是這樣的:

server.port=8080

在這個檔案裡我們可以新增框架支援的配置項,比如專案埠號、JDBC連線的資料來源、日誌級別等等。

現在比較流行的是將properties檔案改為yml檔案。yml檔案的格式yaml是這樣的:

server:
    port: 8080

yml和properties的作用是一樣的。而yml的好處是顯而易見的——更易寫易讀。

屬性之間互相呼叫使用${name}:

eknown:
    email: [email protected]
    uri: http://www.eknown.cn
    title: 'hello, link to ${eknown.uri} or email to ${eknown.email}'

連結:SpringBoot所有官方配置屬性


2.2 多環境配置檔案

通常開發一個應用會有多個環境,常見如dev/prod,也會有test,甚至其他一些自定義的環境,SpringBoot支援配置檔案的靈活切換。

定義新配置檔案需要遵循以下格式:application-{profile}.properties 或者application-{profile}.yml

比如現在有dev和prod兩個環境,我需要在application.yml檔案之外新建兩個檔案:

  1. application-dev.yml

    server:
       port: 8080
  2. application-prod.yml

    server:
      port: 8081

然後在application.yml中通過application.profiles.active={profile}指明啟用那個配置:

application:
    profiles:
      active: dev

除了在application.yml中指定配置檔案外,還可以通過啟動命令指定:java -jar xxx.jar --spring.profiles.active=dev


2.2 自定義配置項並獲取它

主要介紹兩種方式,獲取單個配置項和獲取多個配置項。

舉例:

eknown:
    email: [email protected]
    uri: http://www.eknown.cn

2.2.1 使用@Value註解獲取單個配置項

@Value("${eknown.email}")
private String email;

@Value("${eknown.uri}")
private String url;

注意:使用@Value註解的時候,所在類必須被Spring容器管理,也就是被@Component、@Controller、@Service等註解定義的類。

2.2.2 獲取多個配置項

第一種,定義一個bean類,通過@Value獲取多個配置項:

@Component
public class MyConfigBean {
  
}

然後我們通過get方法來獲取這些值:

@RestController
public class BasicAction {
  
  @Autowired
  private MyConfigBean myConfigBean;

}

第二種,使用註解@ConfigurationProperties:

@Component
@ConfigurationProperties(perfix="eknown")
public class MyConfigBean {

  private String email;
  private String uri;
}

這裡只需要通過prefix指定字首即可,後面的值自動匹配。

這裡我們還使用了@Component註解來讓spring容器管理這個MyConfigBean。

此外,我們可以不需要引入@Component,轉而在Application啟動類上加上@EnableConfigurationProperties({MyConfigBean.class})來啟動這個配置。

注意:我們這裡是從主配置檔案,也就是SpringBoot預設的application-profile檔案中獲取配置資料的。

而從自定義的配置檔案,比如test.yml這種形式中獲取配置項時,情況是有點不大一樣的。


三、自定義配置檔案

上面介紹的配置檔案都是springboot預設的application開頭的檔案。如果要自定義一個配置檔案呢,比如test.yml或test.properties,怎麼獲取其中的配置項呢?

使用@PageResource註解即可。

首先我們來看一下讀取自定義的properties檔案裡的內容:

test.properties

hello.time=2019.11.19
hello.name=eknown

定義Configuration類:

@Configuration
@PropertySource("classpath:test.properties")
//@PropertySource("classpath:test.yml") // 注意,yml檔案不能直接這樣寫,會讀不出資料
@ConfigurationProperties(prefix = "hello")
public class TestConfiguration {
    private String name;
    private String time;

    // hide get and set methods
}

測試一下:

@RestController
@RequestMapping(value = "test")
public class TestAction {

    @Autowired
    private TestConfiguration testConfiguration;

    @GetMapping(value = "config")
    public String test() {
        return testConfiguration.getName() + "<br/>" + testConfiguration.getTime();
    }
}


如果將properties檔案換成yml檔案呢?

我們嘗試一下,發現:

讀不出資料?

分析一下@PropertySource註解,發現其使用的PropertySourceFactory是DefaultPropertySourceFactory.

這個類的原始碼如下:

public class DefaultPropertySourceFactory implements PropertySourceFactory {
    public DefaultPropertySourceFactory() {
    }

    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource);
    }
}

這個類只能處理properties檔案,無法處理yml檔案。所以我們需要自定義一個YmlSourceFactory。

public class YamlSourceFactory extends DefaultPropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        return new YamlPropertySourceLoader().load(resource.getResource().getFilename()
                , resource.getResource()).get(0);
    }
}

然後定義test.yml檔案的config類:

@Configuration
@PropertySource(value = "classpath:test.yml", encoding = "utf-8", factory = YamlSourceFactory.class)
@ConfigurationProperties(prefix = "yml.hello")
public class TestYamlConfiguration {
    private String name;
    private String time;

    // hide get and set methods
}

注:為了區分test.properties和test.yml,這裡的test.yml中的屬性以yml.hello開頭。

編寫一下測試:

    @Autowired
    private TestYamlConfiguration ymlConfiguration;

    @GetMapping(value = "yml")
    public String testYml() {
        return "yml config: <br/>" + ymlConfiguration.getName() + "<br/>" + ymlConfiguration.getTime();
    }

訪問:


四、補充@ConfigurationProperties

網上一些資料中,為配合使用@ConfigurationProperties,還使用了@EnableConfigurationProperties註解。

經過測試發現:

  1. 從SpringBoot預設配置檔案讀取配置資訊,使用@ConfigurationProperties + @Component/@Configuration,或者@ConfigurationProperties + 在啟動類新增@EnableConfigurationProperties({class})。這兩種方式都能解決問題

  2. 從非預設配置檔案讀取配置資訊,需要利用@PropertySource註解。同樣兩種方式:

    2.1 @PropertySource + @ConfigurationProperties + @Component/@Configuration

    2.2 @PropertySource + @ConfigurationProperties + @Component/@Configuration + @EnableConfigurationProperties,第二種方式存在一個問題,即還是必須要使用@Component註解,如果不使用,則會導致讀取配置資訊為null,但程式不會報錯;而如果採用了,則會導致bean類的set方法被執行兩次(也就是生成了兩個同樣型別的bean類)。這種方式不建議!