一、配置文件注入
以前要给bean的属性注入值,需要在xml中这样配置
<bean class="cn.fg.Person">
<property name="name" value="张三" />
<property name="age" value="18" />
</bean>
现在可以通过@ConfigurationProperties注解,将配置文件的值注入到bean属性上;该注解可以用在类和方法上,配置文件的内容只能写在application.properties或application.yml中。
注解使用在类上:
//prefix = "person" 将配置文件以person前缀的属性注入进来,prefix也可以不写,则不区分前缀
@ConfigurationProperties(prefix = "person")
//@ConfigurationProperties("person") //也可以直接这样写
@Component //使用@Component注解,将Person类托管给ioc容器
public class Person {
private String name;
private String realName;
private int age;
private Map<String, Object> maps;
private List<Object> lists;
private String remark;
....省略getter和setter方法
}
#properties写法
person.name=zhangsan
person.age=18
person.lists=1,2,3
person.lists[3] = 4
person.lists[4] = 5
person.maps.name=abc
person.maps.age=17
#yaml写法(springboot推荐使用yaml)
person:
name: 李四
#real-Name real_name也可以,支持松散绑定
realName: 李四
age: 19
lists: [a,b,c]
maps: {name: a1,age: a2}
<!-- 添加此依赖后,在配置文件中输入person.时sts工具会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional> <!-- Maven optional 解读 https://www.cnblogs.com/FraserYu/p/11796301.html -->
</dependency>
注解使用在方法上:
package com.example.demo;
//创建Hello类
public class Hello {
private String nameString;
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
}
package com.example.demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//创建一个配置类
@Configuration
public class HelloConfig {
@ConfigurationProperties("hello") //注入Hello类的属性值
@Bean //注册Hello为一个spring bean
public Hello hello () {
Hello hello = new Hello();
hello.setNameString("李四"); //这里即使赋值了,最终还是会被属性文件中的值覆盖
return hello;
}
}
#application.yml
hello:
name-string: 赵六
使用方法三:
大家发现没有,上述例子@ConfigurationProperties注解想要生效,所在类或所在方法必须是一个spring 注册的bean,现在我们来使用另外一种用法,这也是自动配置的原理之一,例如HttpEncodingAutoConfiguration
#该类仅标注@ConfigurationProperties注解
@ConfigurationProperties(prefix = "ftp")
public class FtpPropert {
private String username;
private String password;
private String address;
private Integer port;
//省略部分代码
}
#application.yml
ftp:
username: test
password: test
address: 127.0.0.1
port: 21
//利用@Configuration和@EnableConfigurationProperties,使FtpPropert.java成为spring bean
@Configuration
@EnableConfigurationProperties(FtpPropert.class)
public class FtpConfig {
//这里没有任何代码,仅仅创建了一个FtpConfig类
}
//在controller中使用
@Autowired
FtpPropert ftpPropert; //因为FtpPropert是spring bean了,所以这里可以注入使用
@RequestMapping("test")
public FtpPropert test() {
return ftpPropert;
}
如果javabean的属性在配置文件中没有找到,则不注入(是不会报错的),如private String remark
@ConfigurationPropertie 与 @Value 比较
综上,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@ConfigurationProperties配合@Validated,实现验证功能
@Validated
@ConfigurationProperties(prefix = "person")
@Component
public class Person {
@Length(max = 50)
private String name;
}
@ConfigurationProperties配合@PropertySource,手动指定properties文件与之绑定,否则@ConfigurationProperties只能使用spring boot 主配置文件绑定(application.properties或application.yml)
@PropertySource(value = {"classpath:person.properties" }) //手动指定properties文件与之绑定,可以指定多个properties
@ConfigurationProperties(prefix = "person")
@Component
public class Person {
}
二、配置文件占位符
person.last-name=张三${random.uuid} #使用随机函数 RandomValuePropertySource
person.dog.age=${person.age} #使用person.age的值
person.dog.name=${person.hello:hello}_dog #使用person.hello的值,如果不存在则使用hello作为默认值
person.age=${random.int}
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
三、多环境配置文件
通常我们在开发、测试、上线时,配置文件的参数都是不一致的,那么在spring boot中该怎么配置多环境呢?
1. 创建多个以application开头的主配置文件 application-xxx.properties或yml
#application.properties
server.port=8080
#application-sit.properties
server.port=8081
#application-prd.properties
server.port=8082
如果按上述创建3个配置文件,则默认加载application.properties,若要使用sit环境,则
#application.properties
server.port=8080
spring.profiles.active=sit #激活某个环境
注意:spring.profiles.active=sit 虽然激活了sit,但是不代表只取sit的值,什么意思?且看下面的例子
#application.properties
person.name=zhangsan
person.height=160
spring.profiles.active=sit
#application-sit.properties
person.height=170
person.age=20
最终person输出:name=zhangsan,age=18,height=170;因此得出一个结论:激活的配置文件与主配置文件会自动合并key,若存在相同的key时,则取激活文件的key;所以application放所有值,application-xxx放变化值
spring.profiles.active=sit,prd 可以激活多个环境
2. 在yml文件中创建多文档块
#在application.yml 使用 --- 分割文档 等同于创建了3个yml文件
spring:
profiles:
active:
- sit
- prd
person:
height: 170
---
spring:
profiles: sit
person:
name: lisi
---
spring:
profiles: prd
person:
age: 25
#最后输出 name=lisi,age=25,height=170
3. 使用命令行参数或JVM参数指定环境
#命令行参数--spring.profiles.active
java -jar spring-boot-demo.jar --spring.profiles.active=prd
#jvm参数
-Dspring.profiles.active=prd
最后 spring.profiles.active的优先级:命令行 > jvm > 配置文件
四、配置文件加载位置及优先级
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
–file:./config/
–file:./
–classpath:/config/
–classpath:/
以上路径优先级由高到底,若key相同的情况下,则高优先级的配置会覆盖低优先级的配置;当application.properties与application.yml同时存在,则properties比yml高
更多配置优先级:https://docs.spring.io/spring-boot/docs/1.5.x/reference/htmlsingle/#boot-features-external-config
1. 关于-file
为工程根路径,若工程打包 此时application.properties是打不进去的,需要手工拷贝放在执行jar的同级目录下。
2. 项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;
java -jar spring-boot-demo.jar --spring.config.location=G:/application.properties