配置文件有分yaml格式和properties和两种格式,可以作为配置文件值注入。映射值的方式有ConfigurationProperties和value两种。同时本章介绍要介绍idea在springboot上的自动单元测试。
1.yaml格式注入文件值
新建两个java文件(分别为Person和Dog),并将yaml的值映射到到java文件属性中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| package com.myblog.springboot.bean;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;
import java.util.Date; import java.util.List; import java.util.Map;
@Component @ConfigurationProperties(prefix = "person") public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; @Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Boolean getBoss() { return boss; } public void setBoss(Boolean boss) { this.boss = boss; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.myblog.springboot.bean; public class Dog { private String name; private Integer age; @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + 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; } }
|
右键resources并新建File,输入文件名为application.yml【这里也可以使用yaml作为结尾】。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| person: lastName: zhangsan age: 18 boss: false birth: 2017/12/12 maps: k1: v1 k2: v2 lists: - lisi - zhaoliu Dog: name: 小狗 age: 2
|
如果在写yaml文件时需要提醒注释,则需要添加下列的依赖。
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional>
|
这里提供我的poml文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu</groupId> <artifactId>spring-boot-02-config</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>
<name>spring-boot-02-config</name> <description>Demo project for Spring Boot</description>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>RELEASE</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
<repositories> <repository> <id>maven-ali</id> <url>http://maven.aliyun.com/nexus/content/repositories/central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> </repository> </repositories>
</project>
|
2.自动单元测试
在src文件夹下的test有提供一个自动单元测试的文件,在我这里是SpingBoot02ConfigApplication
Tests.java。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.myblog.springboot;
import com.myblog.springboot.bean.Person; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class) //用SpringRunner驱动器来跑 @SpringBootTest //SpringBoot单元测试; public class SpringBoot02ConfigApplicationTests {
@Autowired Person person;
@Test public void contextLoads() { System.out.println(person); }
}
|
然后使用@Test旁边的运行符就可以运行自动单元测试,此时会将yaml里的值赋值给自动单元测试模块,效果如下。
3.properties格式注入文件值
使用上面的文件并将创建的yaml文件删除后,使用properties文件。
1 2 3 4 5 6 7 8 9
| person.last-name=张三${random.uuid} person.age=${random.int} person.birth=2017/12/15 person.boss=false person.maps.k1=v1 person.maps.k2=14 person.lists=a,b,c person.dog.name=${person.hello:hello}_dog person.dog.age=15
|
按照前面说明的自动单元测试的方法运行后,可以同样看到文件值的注入,如下所示。
但是我们可以注意到中文出现乱码的情况,需要将properties设置由原本的GBK设置为UTF-8,同时勾选转换为ascill。【在setting中输入file enc可以找到】,记得设置完,要回去把properties文件的乱码修改正常。再运行程序就可以正常运行了。
【GBK设置是每次项目生成时都会设置的,如果要使用中文,则需要在项目生成后就进行设置,以免出错】。
4.不同的文件获取值的方式
上述所用的文件获取值的方式都是基于ConfigurationProperties方式,这里还有一种value的方式可以获取。
value可以获取字面值;从环境变量、配置文件中获取值;还可以获取spring运算值。
将第1小节中的Person.java文件修改为如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| package com.myblog.springboot.bean;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Value;
import java.util.Date; import java.util.List; import java.util.Map;
@Component
public class Person {
@Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; @Value("true") private Boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog;
@Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public Boolean getBoss() { return boss; }
public void setBoss(Boolean boss) { this.boss = boss; }
public Date getBirth() { return birth; }
public void setBirth(Date birth) { this.birth = birth; }
public Map<String, Object> getMaps() { return maps; }
public void setMaps(Map<String, Object> maps) { this.maps = maps; }
public List<Object> getLists() { return lists; }
public void setLists(List<Object> lists) { this.lists = lists; }
public Dog getDog() { return dog; }
public void setDog(Dog dog) { this.dog = dog; } }
|
此时运行自动测试单元,可以得到如设置值一样的效果。
我们可以注意到ConfigurationProperties和value两种方式的不同之处。
|
ConfigurationProperties |
value |
| 功能 |
批量注入配置文件中的属性 |
一个个指定 |
| 松散绑定(松散语法) |
支持 |
不支持 |
| SpEL |
不支持 |
支持 |
| JSR303数据校验 |
支持 |
不支持 |
| 复杂类型封装 |
支持 |
不支持 |
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value。
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties。
这里需要清楚的是ConfigurationProperties和value都是在主配置中的属性映射到实体类中所对应的属性里,下一章才会讲怎么从其他地方加载指定的属性文件的配置到环境中。