目录
SpringBoot的配置文件
yaml是什么?
yaml的语法
注入配置文件
yaml注入配置文件
yaml的占位符
加载指定的配置文件
properties
@Value与@ConfigurationProperties对比
@ConfigurationProperties的松散绑定
@ConfigurationProperties的JSR303数据校验
SpringBoot使用一个全局的配置文件,配置名称是固定的。properties格式或者yaml格式,官方推荐yaml格式。
#Properties配置端口
server.port=8081
#yaml配置端口
server:
port: 8081
配置文件的作用:修改SpringBoot的自动配置的默认值,因为SpringBoot在底层都为我们配置好了。
官方说,YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。
(????)
yaml的语法可以表达清单,散列表,标量等数据形态,很适合来表达或者编辑数据结构,各种配置文件。
因为这种特性,它相比原来的xml来当作配置文件,或者properties来当作配置文件有更强大的功能,所以Spring官方推荐它作为配置文件的格式。
yaml可以存放普通的键值对,对象,数组,格式如下。
#普通的key-value
name: claw
#对象
student:
name: claw
age: 3
#行内写法
student2: {name: claw,age: 3}
#数组(List,Set)
pets:
- cat
- dog
- pig
#数组的行内写法
pets2: [cat,dog,pig]
定义两个实体类,为了它能被扫描到,所以加了@Compnent注解,待会会在测试类用到。
Dog类
/**
* @author Claw
*/
@Component
public class Dog {
private String dogName;
private int age;
//有参无参构造、get、set方法、toString()方法 已省略
}
Person类
/**
* @author Claw
*/
@Component
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map maps;
private List
在resource下创建application.yaml ,并写好person对象里的值。
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map maps;
private List
那么如何将它注入到类里呢?我们用到了@ConfigurationProperties这个注解,它可以将配置文件中配置的每一个属性的值映射到这个组件中,参数 prefix="person":将配置文件中的person下面的属性一一对应。
在使用@ConfigurationProperties 注解的时候IDEA会提示Spring Boot配置注解处理器没有找到,不过SpringBoot是给出了解决办法的,打开网页文档就能找到一个依赖,把它放在pom.xml就能解决这个问题。
如果使用了最新版本的SpringBoot,相关的文档也许没来得及生成,将红框处的版本降低一些就能打开了。比如我就输入了2.1.9的版本打开。
其实就是 这段依赖,导入就可以了。
org.springframework.boot
spring-boot-configuration-processor
true
测试一下
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private Person person;
@Test
public void test(){
System.out.println(person);
}
}
运行,成功注入!
Person{name='claw', age=12, happy=true, birth=Tue Sep 11 00:00:00 GMT+08:00 2001, maps={k1v1=, k2k1=}, lists=[code, music, boy], dog=Dog{dogName='烧鸡', age=1}}
yaml能够给实体类赋值,当然也能当作配置文件来使用,比如配置数据源的时候,driverClass,url,username,password这些值当然也能直接注入,这里就不具体举例了。
yaml里还可以使用随机数和占位符
person:
name: claw${random.uuid} #生成随机UUID
age: ${random.int} #生成随机数
happy: true
birth: 2001/9/11
maps: {k1:v1,k2:k1}
lists:
- code
- music
- boy
dog:
#如果person.hello这个值存在,则默认值为hello,现在我们没有这个默认值,所以dogName这一行会输出hello烧鸡
dogName: ${person.hello:hello}烧鸡
age: 1
测试一下 可以看到name属性后生成了随机的uuid,age生成了随机数,而dogName这一行因为没有person.hello这个属性的存在,使用了默认值hello
Person{name='claw25c0a182-5428-4546-b701-84a907f6153d', age=2145059362, happy=true,
birth=Tue Sep 11 00:00:00 GMT+08:00 2001,
maps={k1v1=, k2k1=}, lists=[code, music, boy], dog=Dog{dogName='hello烧鸡', age=1}}
现在我们在resource文件夹新建一个person.properties文件,我指定了person的name属性的值为claw。
person.name="claw"
那么在Person实体类我用到了@PropertySource这个注解来引入配置文件,并用@Value给name属性赋值,并且我使用了Spring的EL表达式,来取出person.properties里的person.name的值。
/**
* @author Claw
*/
@Component
//@ConfigurationProperties(prefix = "person")
@PropertySource("classpath:person.properties")
public class Person {
@Value("${name}")
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map maps;
private List
这样也是能赋值成功的,其他属性没有赋值所以是null。
Person{name='claw', age=null, happy=null, birth=null, maps=null, lists=null, dog=null}
@Value与@ConfigurationProperties注解都能为属性赋值,但@ConfigurationProperties能灵活。
两个注解的对比:
关于@ConfigurationProperties的松散绑定,拿Dog类举例,狗狗的名字 是dogName这个属性
/**
* @author Claw
*/
@ConfigurationProperties(prefix = "dog")
//@PropertySource("classpath:person.properties")
@Component
public class Dog {
private String dogName;
private int age;
//有参无参构造、get、set方法、toString()方法 已省略
}
在配置文件里,可以表示为 dog-name,同样能够赋值
dog:
dog-name: 烧鸡
age: ${random.int}
测试一下
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private Person person;
@Autowired
private Dog dog;
@Test
public void test() {
System.out.println(dog);
}
}
结果:
Dog{dogName='烧鸡', age=240294096}
这要用到@Validated这个注解了,它可以校验数据的格式。
拿Person类举例,我希望name必须以Email的格式来输入,那么我在Person类打上@Validated这个注解,再在name属性打上@Email的注解。
/**
* @author Claw
*/
@Component
@ConfigurationProperties(prefix = "person")
//@PropertySource("classpath:person.properties")
@Validated
public class Person {
@Email
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map maps;
private List
此时我在application.yaml配置文件里仍然保持person.name的值为claw
person:
name: claw
此时再测试,显示测试失败,并且也给出了错误原因。
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException:
Failed to bind properties under 'person' to com.claw.springboot.pojo.Person failed:
Property: person.name
Value: claw
Origin: class path resource [application.yaml]:24:9
Reason: 不是一个合法的电子邮件地址
这里只举出了@Email,它还支持很多格式的校验,参考:JSR-303
以及通过引入了@Email的时候可以看到它导入了 javax.validation.constraints.Email,追根溯源可以找到所有的constraints
参考:yaml语法学习