Spring Boot号称可以去除XML,但未做到零配置,它体现出了一种”习惯优于配置”的思想,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。 一般情况下默认的配置足够满足日常开发所需,但在特殊的情况下,我们往往需要用到自定义属性配置、自定义文件配置、多环境配置、外部命令引导等一系列功能。对于这些功能,Spring Boot都给予了很好的支持。
│ pom.xml
│ springboot-02-configuration.iml
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─zhuoli
│ │ │ └─service
│ │ │ └─springboot
│ │ │ └─configuration
│ │ │ │ SpringBootConfigurationApplicationContext.java
│ │ │ │
│ │ │ ├─controller
│ │ │ │ CustomPropertiesController.java
│ │ │ │
│ │ │ └─service
│ │ │ GetApplicationProperties1.java
│ │ │ GetApplicationProperties2.java
│ │ │ GetProfileProperties.java
│ │ │ GetZhuoLiProperties.java
│ │ │
│ │ └─resources
│ │ application-dev.properties
│ │ application-prod.properties
│ │ application.properties
│ │ zhuoli.properties
pom.xml配置与上一节相同
-
自动配置
自动配置是Spring Boot的最大亮点,Spring Boot能自动配置Spring各种子项目(Spring MVC, Spring Security, Spring Data, Spring Cloud, Spring Integration, Spring Batch等)以及第三方开源框架所需要定义的各种Bean。Spring Boot内部定义了各种各样的XxxxAutoConfiguration配置类,预先定义好了各种所需的Bean,只有在特定的情况下这些配置类才会被起效。
大多数情况下,自动配置的 Bean 满足了现有的业务场景,不需要去覆盖。但如果自动配置做的不够好,需要覆盖配置。Spring Boot不单单从 application.properties获取配置,Spring Boot中配置文件可以有多种,并且各自有着相应的优先级,如下:
- 命令行参数
- java:comp/env 里的 JNDI 属性
- JVM 系统属性
- 操作系统环境变量
- RandomValuePropertySource 属性类生成的 random.* 属性
- 应用以外的 application.properties(或 yml)文件
- 打包在应用内的 application.properties(或 yml)文件
- 在应用 @Configuration 配置类中,用@PropertySource注解声明的属性文件
- SpringApplication.setDefaultProperties 声明的默认属性
-
自定义属性配置
自定义属性配置是指在application.properties文件中自定义属性,利用Spring Boot会自动加载application.properties文件配置的特性,实现自定义属性的生效。在application.properties文件中写入如下配置内容:
zhuoli.name=zhuoli
zhuoli.age=22
获取application.properties文件中定义的属性,下面介绍两种方式,
@Component
@ConfigurationProperties(prefix = "zhuoli")
public class GetApplicationProperties1 {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "GetProperties1{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@Component
public class GetApplicationProperties2 {
@Value("${zhuoli.name}")
private String name;
@Value("${zhuoli.age}")
private Integer age;
@Override
public String toString() {
return "GetProperties2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
定义Controller,测试是否可以正常获取application.properties文件中自定义属性
@RestController
@RequestMapping("/properties")
public class CustomPropertiesController {
@Autowired
private GetApplicationProperties1 getApplicationProperties1;
@Autowired
private GetApplicationProperties2 getApplicationProperties2;
@RequestMapping(value = "/get1", method = RequestMethod.GET)
public String getCustomProperties1() {
return getApplicationProperties1.toString();
}
@RequestMapping(value = "/get2", method = RequestMethod.GET)
public String getCustomProperties2() {
return getApplicationProperties2.toString();
}
}
按照上节提示,Intellij Idea配置 Edit Configurations启动程序并启动程序,浏览器访问“http://127.0.0.1:8080/properties/get1”、“http://127.0.0.1:8080/properties/get2”可以看到自定义属性已正常注入。
GetProperties1{name='zhuoli', age=22}
GetProperties2{name='zhuoli', age=22}
-
自定义文件配置
在resources文件夹下自定义一个名为 zhuoli.properties 的资源文件
zhuoli.name=zhuoli
zhuoli.age=22
zhuoli.work=programer
定义GetZhuoLiProperties类,用来获取在zhuoli.properties文件中定义的属性
@Component
@PropertySource("classpath:zhuoli.properties")
@ConfigurationProperties(prefix = "zhuoli")
public class GetZhuoLiProperties {
private String name;
private Integer age;
private String work;
//get and set
@Override
public String toString() {
return "GetZhuoLiProperties{" +
"name='" + name + '\'' +
", age=" + age +
", work='" + work + '\'' +
'}';
}
}
CustomPropertiesController中添加映射,测试自定义属性是否正常获取
@RequestMapping(value = "/get3", method = RequestMethod.GET)
public String getZhuoLiProperties() {
return getZhuoLiProperties.toString();
}
浏览器访问”http://127.0.0.1:8080/properties/get3″,可以看到自定义属性文件内容已正常获取
GetZhuoLiProperties{name='zhuoli', age=22, work='programer'}
-
多环境化配置
很多场景的配置,比如数据库配置、Redis 配置、注册中心和日志配置等。在不同的环境,我们需要不同的配置,但如果每次切环境之前还要修改代码或者配置文件未免太过复杂,Spring提供”spring.profile.active”用于指定当前激活的配置文件。只需要定义格式为”application-{profile}.properties”的properties文件(注意application为前缀不能改,{profile}是我们自己定义的),并在application.properties文件中通过spring.profile.active指明生效的profile,相应的properties文件就会生效。首先,定义application-dev.properties、application-prod.properties两个文件
profile.test.env=dev
profile.test.desc=environment: ${profile.test.env}
profile.test.env=prod
profile.test.desc=environment: ${profile.test.env}
定义GetProfileProperties类,用来获取配置文件中定义的属性
@Component
@ConfigurationProperties(prefix = "profile.test")
public class GetProfileProperties {
private String env;
private String desc;
//get and set
@Override
public String toString() {
return "ProfileProperties{" +
"env='" + env + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
application.properties文件中添加一行spring.profiles.active=prod,激活prod环境配置文件:
spring.profiles.active=prod
浏览器访问”http://127.0.0.1:8080/properties/get4″,可以看到prod环境自定义属性内容已正常获取
ProfileProperties{env='prod', desc='environment: prod'}
将application.properties文件中spring.profiles.active=prod,修改为spring.profiles.active=dev,激活dev环境配置文件,浏览器访问”http://127.0.0.1:8080/properties/get4″,可以看到dev环境自定义属性内容已正常获取
ProfileProperties{env='dev', desc='environment: dev'}
由此看一看出,不同环境的配置文件被选择性激活,这再配置数据库、redis、日志等场景时是非常常见的
-
外部命令配置
上一节讲了多环境配置,考虑这样一种场景,加入代码已正常打包,这时候发现application.properties文件中spring.profiles.active没有改成prod,这样生效的配置还是dev环境的,肯定是没办法发布的,但是根据本文第一节的配置优先级的讲解,我们应该是可以通过优先级更高的方式来覆盖application.properties文件中的配置。步骤如下:
- 通过maven将项目打包成jar
- 输入:java -jar springboot-02-configuration-1.0-SNAPSHOT.jar –spring.profiles.active=prod
- 浏览器访问”http://127.0.0.1:8080/properties/get4″,查看prod环境配置文件是否生效
参考链接:
- Java EE开发的颠覆者 – Spring Boot实战
- Spring官方文档 – Spring IO