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...