Spring Boot 對於開發人員最大的好處在於能夠對 Spring 應用進行自動配置。Spring Boot 會根據應用中聲明的第三方依賴來自動配置 Spring 框架,而不須要進行顯式的聲明。好比當聲明瞭對 HSQLDB 的依賴時,Spring Boot 會自動配置成使用 HSQLDB 進行數據庫操做。
Spring Boot 的自動配置功能是沒有侵入性的,只是做爲一種基本的默認實現。開發人員能夠經過定義其餘配置 bean 來替代自動配置所提供的功能(使用@Configuration註解)。好比當應用中定義了本身的數據源 bean 時,自動配置所提供的 HSQLDB 就不會生效。這給予了開發人員很大的靈活性,既能夠快速的建立一個能夠當即運行的原型應用,又能夠不斷的修改和調整以適應應用開發在不一樣階段的須要。Spring Boot 使得這樣的切換變得很簡單。java
注意,自動配置永遠是第二位的,一旦你配置本身的東西,那自動配置的就會被覆蓋。mysql
在應用中管理配置並非一個容易的任務,尤爲是在應用須要部署到多個環境中時。一般會須要爲每一個環境提供一個對應的屬性文件,用來配置各自的數據庫鏈接信息、服務器信息和第三方服務帳號等。一般的應用部署會包含開發、測試和生產等若干個環境。不一樣的環境之間的配置存在覆蓋關係。Spring Boot 提供了一種統一的方式來管理應用的配置,容許開發人員使用屬性文件、YAML 文件、環境變量和命令行參數來定義優先級不一樣的配置值。
Spring Boot 所提供的配置優先級順序比較複雜。按照優先級從高到低的順序,具體的列表以下所示。git
System.getProperties()
獲取的 Java 系統參數。@Configuration
註解的 Java 類)中經過@PropertySource
註解聲明的屬性文件。SpringApplication.setDefaultProperties
聲明的默認屬性。Spring Boot 的這個配置優先級看似複雜,實際上是很合理的。好比命令行參數的優先級被設置爲最高。這樣的好處是能夠在測試或生產環境中快速地修改配置參數值,而不須要從新打包和部署應用。github
SpringApplication 類默認會把以「--」開頭的命令行參數轉化成應用中可使用的配置參數,如 「--name=Alex」 會設置配置參數 「name」 的值爲 「Alex」。好比在啓動一個Spring Boot項目的時候使用java -jar ${項目名}.jar --server.port=9090
命令,則該項目的端口就被設置成了9090.web
屬性文件是最多見的管理配置屬性的方式。Spring Boot 提供的 SpringApplication 類會搜索並加載 application.properties 文件來獲取配置屬性值。SpringApplication 類會在下面位置搜索該文件。spring
* 當前目錄的「/config」子目錄。 * 當前目錄。 * classpath 中的「/config」包。 * classpath
上面的順序也表示了該位置上包含的屬性文件的優先級。優先級按照從高到低的順序排列。sql
對於配置屬性,能夠在代碼中經過「@Value」註解來使用,這點和普通的Spring項目同樣。以下例:
建立一個SpringBoot的Maven項目,項目結構以下:數據庫
pom.xml文件中引入Spring Boot Parent和Spring Boot Web的依賴:springboot
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.7.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version> </dependency> </dependencies>
在resources目錄下建立一個名爲application.properties 的文件,將以下內容添加至該文件:服務器
book.name=HongLouMeng book.author=曹雪芹 book.publisher=\u4e09\u8054\u51fa\u7248\u793e book.price=68.5
建立啓動類:
package com.ddcx.springboot.democonfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ConfigDemoApplication { public static void main(String[] args) { //讀取默認配置文件的啓動方式 SpringApplication.run(ConfigDemoApplication.class, args); } }
再建立一個controller類,在這個類中就能夠經過@Value從配置文件中獲取配置好的值:
package com.ddcx.springboot.democonfig.controller; import com.ddcx.springboot.democonfig.entity.Book; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { @Value("${book.name}") private String bookName; @Value("${book.author}") private String bookAuthor; @Value("${book.publisher}") private String publisher; @Value("${book.price}") private String price; @RequestMapping("/bookInfo") String bookInfo() { return "bookName-->" + bookName + "\nbookAuthor-->" + bookAuthor + "\npublisher-->" + publisher + "\nprice-->" + price ; } }
在postman中發送請求獲得以下結果:
properties文件中的中文出現了亂碼問題,能夠在properties文件中改用unicode編碼的方式。
除此以外,還能夠配置服務器端口、數據庫等各類配置:
# 配置服務器端口爲8090 server.port=8090 # 配置應用的根路徑,必須以'/'開頭,不然會報異常: # java.lang.IllegalArgumentException: ContextPath must start with '/ and not end with '/' server.context-path=/demo-config
除了使用@Value
註解綁定配置屬性值以外,還可使用@ConfigurationProperties(prefix="book")
註解,配置屬性中以「book」爲前綴的屬性值會被自動綁定到 Java 類中同名的屬性上,前提是要有屬性的set方法。這種方法能夠方便地配置數據庫。
在這個示例中好比建立一個Book類:
package com.ddcx.springboot.democonfig.entity; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component //由於要使用自動注入,因此要掃描註冊到ioc容器中 @ConfigurationProperties(prefix="book") public class Book { private String name; private String author; private String publisher; private double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }
在前面縮寫的DemoController中自動注入一個Book屬性,添加以下代碼:
private static Gson gson = new Gson(); @Autowired private Book book; @RequestMapping("/prefixConfigTest") String prefixConfigTest() { return gson.toJson(book); }
在postman中測試代表也能夠獲取到application.properties中的配置,而且服務器的端口配置也能夠同時獲得驗證:
前面講到,默認狀況下SpringBoot 會去指定的路徑下搜索文件名稱爲 application.yml、application.properties的配置文件,那如何本身定義配置文件名?
在SpringBoot中能夠經過「spring.config.name」配置屬性來指定不一樣的屬性文件名稱。也能夠經過「spring.config.location」來添加額外的屬性文件的搜索路徑。若是應用中包含多個 profile,能夠爲每一個 profile 定義各自的屬性文件,按照「application-{profile}」來命名。
接下來能夠實際操做一下,首先在resources目錄下再建立一個 springboot-config.properties 的文件,
並在配置文件中添加內容:
book.name=Effective Java book.author=Joshua Bloch server.port=8070
在將啓動類的啓動方式改爲以下:
package com.ddcx.springboot.democonfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @SpringBootApplication public class ConfigDemoApplication { public static void main(String[] args) { //讀取默認配置文件的啓動方式 //SpringApplication.run(ConfigDemoApplication.class, args); //讀取自定義配置文件名的啓動方式 new SpringApplicationBuilder(ConfigDemoApplication.class) .properties("spring.config.location=classpath:/springboot-config.properties") .run(args); } }
訪問結果:
這裏會有一個現象,若是 application.properties 和 springboot-config.properties 兩個文件同時存在,當application.properties中的配置在pringboot-config.properties也一樣配置了,好比上面的bookName,那麼pringboot-config.properties中的配置優先級更高,當application.properties中的配置在pringboot-config.properties沒有配置,那麼application.properties中的那項配置仍然會起做用,好比上面的publisher和server.context-path等。可是若是將 application.properties文件名改爲其它的,好比 application-config.properties,則徹底以pringboot-config.properties這個配置文件爲準。
除了屬性文件,SpringApplication 類也提供了對 YAML 配置文件的支持,下面給出了 application.yml 文件的示例。
注意:使用.yml時,屬性名的值和冒號中間必須有空格,如branch: master
正確,branch:master
就是錯的。
user: username: 張三 age: 22 contactAddress[0]: province: hunan city: changsha area: yuhuaqu contactAddress[1]: province: guangdong city: guangzhou area: tianhequ
SpringBoot的配置支持嵌套和幾何配置,對於上面的配置,對應以下User和Address兩個類:
package demoyaml.entity; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.List; /** * Created by liaosi on 2017/10/7. */ @Component @ConfigurationProperties(prefix = "user") public class User { private String username; private Integer age; private List<Address> contactAddress; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<Address> getContactAddress() { return contactAddress; } public void setContactAddress(List<Address> contactAddress) { this.contactAddress = contactAddress; } }
package demoyaml.entity; /** * Created by liaosi on 2017/10/7. */ public class Address { private String province; private String city; private String area; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } }
在Controller中添加訪問這個配置的user對象的方法:
package demoyaml.controller; import com.google.gson.Gson; import demoyaml.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { private static Gson gson = new Gson(); @Autowired private User user; @RequestMapping("/getUser") String getUser() { return gson.toJson(user); } }
訪問結果:
在實際開發中,一般會有開發、測試、生產等多種環境,SpringBoot是怎麼來配置多種環境的呢?
(1)在項目中添加不一樣環境的配置文件
(2)在application.properties配置文件中配置須要激活那個環境:
#激活哪個環境的配置文件 spring.profiles.active=dev #公共配置 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss:
在application中增長內容:
#激活哪個環境的配置文件 spring: profiles: active: development --- spring: profiles: development db: url: jdbc:hsqldb:file:testdb username: dev password: dev #在配置文件增長三個短橫線區分不一樣的環境 --- spring: profiles: test db: url: jdbc:mysql://localhost/test username: test password: test
定義一個DBConfig類,獲取激活的那個環境的配置:
package demoyaml.entity; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "db") public class DBConfig { private String url; private String username; private String password; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
經過controller中的方法查看:
package demoyaml.controller; import com.google.gson.Gson; import demoyaml.entity.DBConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { private static Gson gson = new Gson(); @Autowired private DBConfig DBConfig; @RequestMapping("/getEnvConfig") String getDBConfig() { return gson.toJson(DBConfig); } }
* Properties配置多環境,須要添加多個配置文件,YAML只須要一個配件文件 * 書寫格式的差別,yaml相對比較簡潔,優雅 * YAML的缺點:不能經過@PropertySource註解加載。若是須要使用@PropertySource註解的方式加載值,那就要使用properties文件。
本節示例代碼已上傳到github: https://github.com/liaosilzu2...