spring boot支持properties和yaml两种配置格式,properties在spring项目中很常见,key value形式配置参数,而yaml 是一种通用的数据串行化格式,专门用来写配置文件的语言,比 JSON 格式方便,支持对象、数组、纯量三种数据结构。建议在spring boot项目中采用yaml方式,让配置结构更加清晰。
1.配置与使用
1.下面以一个实例来说明其使用,先看properties格式配置
application.properties
server.port=8000
jdbc_url=jdbc:mysql://127.0.0.1:3306/test
student.id=1003
student.name=tom
student.age=30
student.desc=${student.name} is a student, ${student.age} years old this year
StudentConfig 配置
@ConfigurationProperties注入配置属性前缀,prefix指定前缀。
@Component
@ConfigurationProperties(prefix="student")
public class StudentConfig {
private String id;
private String name;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
ConfigController:
@Value注入配置文件属性值,冒号分割“:”,不存在取默认。
@RestController
public class ConfigController {
@Value("${jdbc_url:jdbc:mysql://localhost:3306/test}")
private String jdbcUrl;
@Value("${student.desc}")
private String desc;
@Autowired
private StudentConfig studentConfig;
@RequestMapping(value="/jdbc",method = RequestMethod.GET)
public String jdbc(){
return jdbcUrl;
}
@RequestMapping(value="/student",method = RequestMethod.GET)
public String studentConfig(){
return studentConfig.toString();
}
@RequestMapping(value="/desc",method = RequestMethod.GET)
public String desc(){
return desc;
}
}
2.启动服务,请求对于的url,可以查看返回的参数
下面用yaml编写配置文件看看,application.yml
server:
port: 8000
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
层次感很强,配置也比properties清晰很多。注意下级比上级缩进2个空格,属性与属性值冒号加空格分割
2.使用Profile区分环境
spring boot中,可以通过在application.yml配置文件中,配置多个不同的profile,实现在不同的环境(比如开发、测试和生产环境)使用不同的配置变量。
如下:
server:
port: 8000
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
# 默认的profile为dev,其他环境通过指定启动参数使用不同的profile
spring:
profiles:
active: dev
---
# 开发环境配置
spring:
profiles: dev
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
---
# 测试环境配置
spring:
profiles: test
jdbc_url: jdbc:mysql://192.168.1.20:3306/test
各个环境配置使用”—”分割,默认启动时dev,如使用其他环境,启动参数增加 :spring.profiles.active=test
如:java -jar my-spring-boot.jar –spring.profiles.active=test
也可以将如上拆分成多个不同环境文件,这个配置更清晰,如:通过文件名来区分环境 application-{profile}.yml
将公共的都放在application.yml里面,因环境变化的都放在application-{profile}.yml文件里
application.yml
server:
port: 8000
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
# 默认的profile为dev,其他环境通过指定启动参数使用不同的profile
spring:
profiles:
active: dev
application-dev.yml
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
application-test.yml
jdbc_url: jdbc:mysql://192.168.1.20:3306/test
在启动程序的时候通过添加 –spring.profiles.active={profile} 来指定具体使用的配置。Spring Boot 会先加载默认的配置文件,然后使用具体指定的profile中的配置去覆盖默认配置。
注:
1.Java类中可以使用@Profile注解指定了具体环境,不建议这样使用。如:
// 接口定义
public interface SendMessage {
// 发送短信方法定义
public void send();
}
// Dev 环境实现类
@Component
@Profile("dev")
public class DevSendMessage implements SendMessage {
@Override
public void send() {
System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
}
}
// Stg环境实现类
@Component
@Profile("stg")
public class StgSendMessage implements SendMessage {
@Override
public void send() {
System.out.println(">>>>>>>>Stg Send()<<<<<<<<");
}
}
// 启动类
@SpringBootApplication
public class ProfiledemoApplication {
@Value("${app.name}")
private String name;
@Autowired
private SendMessage sendMessage;
@PostConstruct
public void init(){
sendMessage.send();// 会根据profile指定的环境实例化对应的类
}
}
2.logback-spring.xml也支持有节点来支持区分,文件名不要用logback.xml 请使用logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="INFO"/>
<springProfile name="default">
<logger name="org.springboot.sample" level="TRACE" />
</springProfile>
<springProfile name="dev">
<logger name="org.springboot.sample" level="DEBUG" />
</springProfile>
<springProfile name="staging">
<logger name="org.springboot.sample" level="INFO" />
</springProfile>
</configuration>
3.指定外部的配置文件
java -jar demo.jar --spring.config.location=/ect/demo/application.properties
3.获取环境变量
凡是被spring管理的类,实现接口 EnvironmentAware 重写方法 setEnvironment 可以在工程启动时,获取到系统环境变量和application配置文件中的变量。
@Configuration
public class AppConfigurer implements EnvironmentAware
{
private static final Logger logger = LoggerFactory.getLogger(AppConfigurer.class);
private RelaxedPropertyResolver propertyResolver;
@Value("${jdbc_url}")
private String jdbcUrl;
@Override
public void setEnvironment(Environment env) {
logger.info(env.getProperty("JAVA_HOME"));
logger.info(jdbcUrl);
String str = env.getProperty("student.name");
logger.info(str);
propertyResolver = new RelaxedPropertyResolver(env, "student.");
String desc= propertyResolver.getProperty("desc");
logger.info(desc);
}
}
@Controller @Service 等被Spring管理的类都支持,注意重写的方法 setEnvironment 是在系统启动的时候被执行。
关于配置读取的几个注解:
实例
@Configuration
@ConditionalOnClass(Redis.class)
@EnableConfigurationProperties(RedisProperties.class)
@ConditionOnClass 表明该@Configuration仅仅在一定条件下才会被加载,这里的条件是Redis.class位于类路径上
@EnableConfigurationProperties 将Spring Boot的配置文件(application.properties)中的spring.data.redis.*属性映射为RedisProperties并注入到RedisAutoConfiguration中。
@ConditionalOnMissingBean 说明Spring Boot仅仅在当前上下文中不存在Redis对象时,才会实例化一个Bean。这个逻辑也体现了Spring Boot的另外一个特性——自定义的Bean优先于框架的默认配置,我们如果显式的在业务代码中定义了一个Redis对象,那么Spring Boot就不再创建。
实例源码:https://github.com/slimina/springboot-study