Spring Boot實踐——用外部配置填充Bean屬性的幾種方法
引用:https://blog.csdn.net/qq_17586821/article/details/79802320
spring boot允許我們把配置資訊外部化。由此,我們就可以在不同的環境中使用同一套程式程式碼。可以使用屬性檔案,yaml檔案,環境變數,命令列引數來實現配置資訊的外部化。可以使用@Value註解來將屬性值直接注入到bean裡邊。也可以使用@ConfigurationProperties註解將屬性值注入到結構化的物件裡邊。
@ConfigurationProperties
Spring boot 應用中,當使用註解方式定義一個Bean時,同時可以利用@ConfigurationProperties匯入外部屬性填充到這個Bean的例項。本文通過例子介紹了幾種用法可以達到這種效果 :
- @ConfigurationProperties + @Component 註解到bean定義類上
- @ConfigurationProperties + @Bean註解在配置類的bean定義方法上
- @ConfigurationProperties註解到普通類然後通過@EnableConfigurationProperties定義為bean
例子所採用配置檔案
先在例子專案增加配置檔案 src/main/resources/application.properties ,其內容如下
section1.name=Tom section2.name=Jerry section3.name=Dog
方式1 : @ConfigurationProperties + @Component 註解到bean定義類上類定義為Bean
// 將類定義為一個bean的註解,比如 @Component,@Service,@Controller,@Repository // 或者 @Configuration @Component // 表示使用配置檔案中字首為 section1 的屬性的值初始化該bean定義產生的的bean例項的同名屬性// 在使用時這個定義產生的bean時,其屬性 name 會是 Tom @ConfigurationProperties(prefix = "section1") public class Bean1 { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
方式2 : @ConfigurationProperties + @Bean註解在配置類的bean定義方法上Bean來自一個普通類
// 這是一個一般java類,POJO,沒有任何註解 public class Bean2 { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
使用@Bean註解將一個配置類的方法定義為一個bean
在專案的某個@Configuration配置類中通過@Bean註解在某個方法上將上面的POJO類定義為一個bean,並使用配置檔案中相應的屬性初始化該bean的屬性。
這裡所說的@Configuration配置類可以是直接通過@Configuration註解的配置類,也可以是隱含使用了@Configuration註解的類,比如下面的例子中,@SpringBootApplication隱含了@Configuration。
// 宣告為Spring boot 應用,隱含了註解@Configuration @SpringBootApplication public class Application { // @Bean 註解在該方法上定義一個bean,這種基於方法的Bean定義不一定非要出現在 // @SpringBootApplication 註解的類中,而是出現在任何@Configuration註解了 // 的類中都可以 @Bean // 使用配置檔案中字首為section2的屬性的值初始化這裡bean定義所產生的bean例項的同名屬性, // 在使用時這個定義產生的bean時,其屬性 name 會是 Jerry @ConfigurationProperties(prefix = "section2") public Bean2 bean2() { // 注意,這裡的 Bean2 是上面所示的一個POJO類,沒有任何註解 return new Bean2(); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
方式3 : @ConfigurationProperties註解到普通類然後通過@EnableConfigurationProperties定義為bean
註解一個普通類的屬性將會來自外部屬性檔案
// 該註解宣告如果該類被定義為一個bean,則對應的bean例項的屬性值將來自配置檔案中字首為 // section3的同名屬性。但是這個註解本身並不會導致該類被作為一個bean註冊 @ConfigurationProperties(prefix = "section3") public class Bean3 { public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
使用@EnableConfigurationProperties將上述類定義為一個bean
@SpringBootApplication // 該註解會將類Bean3作為一個bean定義註冊到bean容器,而類Bean3上的註解 // @ConfigurationProperties(prefix = "section3")會導致目標bean // 例項的屬性值使用配置檔案中字首為section3的同名屬性值來填充,也就是目標 // bean的屬性name的值會是Dog @EnableConfigurationProperties({Bean3.class}) public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
注意重點:
- 使用@ConfigurationProperties,在這種繫結中,getter 和 setter 方法是強制的,因為這裡的繫結是通過標準的Java Bean屬性繫結,但是也有例外。
- 屬性配置類的屬性名和配置檔案中配置資訊是對應的(這裡的對應並不是要求一模一樣,只要能轉換成功,就算對應,比如下劃線語法、駝峰語法等都能接受)
@Value
- @Value+ @Component 註解到bean定義類上
- @Value+ @Bean註解在配置類的bean定義方法上
實現方式同上只是要寫全對應的名
配置檔案
book.author=onlymate
book.name=Java is s magic
對應的bean
@Bean //@Component @PropertySource("classpath:files/el.properties") public class CustomElConfig { //注入普通字串 @Value("I Love YOU!") private String normal; //注入作業系統屬性 @Value("#{systemProperties['os.name']}") private String osName; //注入表示式結果 @Value("#{T(java.lang.Math).random()*100.0}") private double randomNumber; //注入其他的bean屬性 @Value("#{customElBean.another}") private String fromAnother; //注入檔案資源 @Value("classpath:files/test.txt") private Resource testFile; //注入網址資源 @Value("http://www.baidu.com") private Resource testUrl; //注入配置檔案 @Value("${book.name}") private String bookNmame; @Value("${book.author}") private String bookAuthor; //注入環境 @Autowired private Environment environment; @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigure(){ return new PropertySourcesPlaceholderConfigurer(); } public void outputResource(){ try { System.out.println(normal); System.out.println(osName); System.out.println(randomNumber); System.out.println(fromAnother); System.out.println(IOUtils.toString(testFile.getInputStream(), Charset.defaultCharset())); System.out.println(IOUtils.toString(testUrl.getInputStream(), Charset.defaultCharset())); System.out.println(bookNmame); System.out.println(environment.getProperty("book.author")); }catch (Exception e){ e.printStackTrace(); System.out.println(e); } } }
這裡不需要寫出set、get方法,屬性名也任意,只要@Value("${book.author}")裡面的key要對應配置檔案中的key