SpringBoot項目有一些基本的配置,好比啓動圖案(banner),好比默認配置文件application.properties,以及相關的默認配置項。html
示例項目代碼在:https://github.com/laolunsi/spring-boot-examplesjava
編寫banner.txt放入resources文件夾下,而後啓動項目便可修改默認圖案。git
關於banner的生成,能夠去一些專門的網站。github
好比:https://www.bootschool.net/asciispring
resources下一般會默認生成一個application.properties文件,這個文件包含了SpringBoot項目的全局配置文件。裏面的配置項一般是這樣的:springboot
server.port=8080
在這個文件裏咱們能夠添加框架支持的配置項,好比項目端口號、JDBC鏈接的數據源、日誌級別等等。app
如今比較流行的是將properties文件改成yml文件。yml文件的格式yaml是這樣的:框架
server: port: 8080
yml和properties的做用是同樣的。而yml的好處是顯而易見的——更易寫易讀。ide
屬性之間互相調用使用${name}:spring-boot
eknown: email: eknown@163.com uri: http://www.eknown.cn title: 'hello, link to ${eknown.uri} or email to ${eknown.email}'
一般開發一個應用會有多個環境,常見如dev/prod,也會有test,甚至其餘一些自定義的環境,SpringBoot支持配置文件的靈活切換。
定義新配置文件須要遵循如下格式:application-{profile}.properties
或者application-{profile}.yml
好比如今有dev和prod兩個環境,我須要在application.yml文件以外新建兩個文件:
application-dev.yml
server: port: 8080application-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
主要介紹兩種方式,獲取單個配置項和獲取多個配置項。
舉例:
eknown: email: eknown@163.com uri: http://www.eknown.cn
@Value("${eknown.email}") private String email; @Value("${eknown.uri}") private String url;
注意:使用@Value註解的時候,所在類必須被Spring容器管理,也就是被@Component、@Controller、@Service等註解定義的類。
第一種,定義一個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,還使用了@EnableConfigurationProperties註解。
通過測試發現:
從SpringBoot默認配置文件讀取配置信息,使用@ConfigurationProperties + @Component/@Configuration,或者@ConfigurationProperties + 在啓動類添加@EnableConfigurationProperties({class})。這兩種方式都能解決問題
從非默認配置文件讀取配置信息,須要利用@PropertySource註解。一樣兩種方式:
2.1 @PropertySource + @ConfigurationProperties + @Component/@Configuration
2.2 @PropertySource + @ConfigurationProperties + @Component/@Configuration + @EnableConfigurationProperties,第二種方式存在一個問題,即仍是必需要使用@Component註解,若是不使用,則會致使讀取配置信息爲null,但程序不會報錯;而若是採用了,則會致使bean類的set方法被執行兩次(也就是生成了兩個一樣類型的bean類)。這種方式不建議!