欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot 配置文件 自定义配置参数

程序员文章站 2022-05-02 07:49:12
...

简介

SpringBoot 通过对 Spring 的封装, 让你在项目中几乎看不到 .xml 文件, 那我们的配置放在哪儿呢? 放在了 src/main/resources 下的 application.properties 文件中. 除了 .properties 文件, SpringBoot 还支持 .yml 文件, 个人比较推荐使用 .yml 格式的文件. 因为他结构清晰, 不需要重复的写相同的头信息.

格式差别

.properties 文件示例:

# 设置端口为 8080
spring.port=8080
# 使用 random 配置文件
spring.profiles.active=random

先不要太在意代码中配置的含义, 只看上面两行配置的结构, 都有 spring 前缀, 但是都要再写一遍

.yml 文件示例:

spring:
    # 设置端口为 8080
    port: 8080
    prifiles:
        # 使用 random 配置文件
        active: random

通过和 .properties 文件的对比, 很容易就发现了两者的不同, .yml 文件的可读性更强一些, 而且不需要重复的写含有相同前缀的头信息.

HelloWorld @Value

创建项目 & 编码

简介好像说的有点多了, 下面我们就来写一个 HelloWorld 实际练一下, 新建一个项目, 不需要引额外的包.

直接上代码

application.yml 文件

# 测试中使用的作者信息
author:
  # 姓名
  name: summer
  # 年龄
  # age: 18
  # 性别
  gender: man

创建实体 AuthorValue.java 代码如下:

/**
 * @author summer
 * @date 2018/4/12 下午3:32
 * 配置文件对应的实体
 */
@Component
public class AuthorValue {
    /**
     * 用户名
     */
    /*
     * 通过 value 注解获取 properties 文件中的内容
     * ${属性的全称}
     */
    @Value("${author.name}")
    private String name;
    /*
     * 若配置文件中没有配置相应的属性, 而在类中又通过 @Value的形式获取, 系统启动时会报错
     * 所以, 我们可以通过设定默认值的形式避免这样的问题
     */
    @Value("${author.age:10}")
    private Integer age;

    // getter and setter
}

创建测试类 AuthorValueTest.java 代码如下:

/**
 * @author summer
 * @date 2018/4/12 下午3:34
 * 通过 value 的方式获取配置文件内容的测试方法
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class AuthorValueTest {

    @Autowired
    private AuthorValue authorValue;

    @Test
    public void getUserMessage(){
        Integer age = 10;
        Assert.assertEquals(authorValue.getName(), "summer");
        Assert.assertEquals(authorValue.getAge(), age);
    }
}

运行测试代码, 发现完美运行.

到此, 我们的 HelloWorld 就开发完成了. What ? 发生了什么? 开发完成了? 其实通过查看代码中的注解, 也能看出相关的逻辑, 接下来我们再做一些补充

代码解释

application.yml

配置文件中我们自己定义了一组属性, 这里的 author, namegender 都是我们自己定义的.

注意: 这里使用的是 yml, 他的语法是用冒号 : 和缩进来确定上下级关系的.

AuthorValue. java

代码中, 我们通过 @Value("${author.name}") 的方式获取了 application.yml 中的 author.name 的值. 值得注意的是, 我们使用 @Value 的方式获取相应的配置参数时, 如果配置文件中没有设置相应的值, 则会报错. 我们可以通过 @Value(参数名:默认值) 的方式给相应的配置加上默认值. 例如示例中的 age 字段.

通过前缀 @ConfigurationProperties 直接封装对象

编码

application.yml 文件内容如下

# 测试中使用的作者信息
author:
  # 姓名
  name: summer
  # 年龄
  age: 18
  # 性别
  gender: man

  # Map 的测试数据
  wife[name]: lili
  wife[age]: 19

  # List 的测试数据
  books[0]: spring
  books[1]: java

新建 AuthorObject.java 内容如下

/**
 * @author summer
 * @date 2018/4/12 下午3:32
 * 配置文件对应的实体
 */
@Component
@ConfigurationProperties(prefix = "author")
public class AuthorObject {
    /**
     * 用户名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 妻子信息, 主要用来演示 map
     */
    private Map<String, Object> wife;
    /**
     * 出品的书籍 用于演示 list
     */
    private List<String> books;

    /**
     * 简介信息, 用于测试配置文件间的参数调用
     */
    private String introduce;
    
    // getter and setter
}

新建测试类 AuthorObjectTest.java 内容如下

/**
 * @author summer
 * @date 2018/4/12 下午3:34
 * 通过 value 的方式获取配置文件内容的测试方法
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class AuthorObjectTest {

    @Autowired
    private AuthorObject authorObject;

    @Test
    public void getUserMessage(){
        Integer age = 18;
        Assert.assertEquals(authorObject.getName(), "summer");
        Assert.assertEquals(authorObject.getAge(), age);
        Assert.assertFalse(authorObject.getWife().isEmpty());
        Assert.assertFalse(authorObject.getBooks().isEmpty());
        Assert.assertNotNull(authorObject.getIntroduce());

        System.out.println("user wife name: " + authorObject.getWife().get("name"));
        System.out.println("user wife name: " + authorObject.getWife().get("age"));

        System.out.println("first boot: " + authorObject.getBooks().get(0));

        System.out.println(authorObject.getIntroduce());
    }
}

代码解释

可能大家已经注意到了, 在 AuthorObject.java 上有个注解 @ConfigurationProperties(prefix = "author") , 这是什么意思呢? 意思就是从 application.yml 文件中查找以 author 开头的自定义配置. 然后封装成对象, 类中的属性名, 需要和配置文件的自定义配置的名称(author下)一致.

除了基础数据类型以外, 我们也可以封装 MapList

封装 Map 的语法: 对应的属性名[Map的Key]:Value

封装 List 的语法: 对应的属性名称[Index]:Value

小结

通过上面两个例子, 我们分别用 @Value@ConfigurationProperties(prefix = "prefix") 的方式获取配置文件中的参数, 在开发过程中大家也应该可以明显的感觉到 @ConfigurationProperties 的便捷. 值得一提的是, 使用后一种方式封装参数时, 即便是配置文件中没有定义相应的属性, 在加载时也不会报错.

多环境配置

在开发过程中, 开发者之间, 为了适应本地环境, 经常要修改配置. 从开发发布到生产服务器的时候, 很多时候也要修改配置, 你也改, 我也改. 不出问题就见鬼了.

SpringBoot 提供了怎样的解决方案呢? 没错, 多环境配置, 每人一个配置文件, 生产服务有自己专门的配置, 这样开发的时候互相之间就不会有影响了. 是不是很爽? 接下来, 我们就看一下多环境是如何实现的.

编码

resources 下新建文件 application-random.yml 内容如下:

author:
  property:
    # 随机字符串
    value: ${random.value}
    # 随机 int
    number: ${random.int}
    # 随机 long
    bignumber: ${random.long}
    # 10 以内的随机数
    number1: ${random.int(10)}
    # 10-20的随机数
    number2: ${random.int[10,20]}

application.yml 中添加配置如下

spring:
  profiles:
    # 设置使用的配置文件为 random 后缀的
    active: random

新建 JavaRandomValue.java 内容如下:

/**
 * @author summer
 * @date 2018/4/12 下午5:28
 */
@Component
public class RandomValue {
    @Value("${author.property.value}")
    private String value;
    @Value("${author.property.number}")
    private Integer number;
    @Value("${author.property.bignumber}")
    private Long bignumber;
    @Value("${author.property.number1}")
    private Integer number1;
    @Value("${author.property.number2}")
    private Integer number2;
    
    // getter and setter 
}

新建测试类 RandomValueTest.java 内容如下

/**
 * @author summer
 * @date 2018/4/12 下午3:34
 * 通过 value 的方式获取配置文件内容的测试方法
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RandomValueTest {

    @Autowired
    private RandomValue randomValue;

    @Test
    public void getUserMessage(){
        Assert.assertNotNull(randomValue.getValue());
        Assert.assertNotNull(randomValue.getNumber());
        Assert.assertNotNull(randomValue.getBignumber());
        Assert.assertNotNull(randomValue.getNumber1());
        Assert.assertNotNull(randomValue.getNumber2());

        System.out.println(randomValue.getValue());
    }
}

右击运行测试类, 完美运行

代码解释

多环境配置时, 我们首先建了一个 application-random.yml 命名规则是 application(默认)-环境名(可自定义).yml

然后在 application.yml 中设置**的环境为 random . 值得注意的是在指定环境后, 主配置文件 application.yml 中的属性也依旧会有效, 如果出现了重复配置, 主配置文件中的内容会被覆盖.

随机数 random

上一小节"多环境配置"中,我们的 application-random.yml 文件里使用了 ${random.value} 用以获取随机数. random 我们都用过. 但是这里是设么意思呢, 这是一种参数间引用. 例如:

# 测试中使用的作者信息
author:
  # 姓名
  name: summer
  # 年龄
  age: 18
  # 性别
  gender: man

  # 参数间的引用
  introduce: Name:${author.name},Age:${author.gender}

我们自己定义了 author namegender 下面 introduce 参数的值, 通过 ${参数名} 的方式引用了上面提到的值. 同理 ${random.value} 也是同样的道理, 不同的是后者引用的不是一个固定的参数, 而是生成一个随机字符串的方法. 除了 random 之外, SpringBoot 还提供了其他的很多常用参数, 例如: os (用于获取系统信息), idea (用于获取开发工具信息), pom (用于获取 maven 配置信息), file 文件的相关处理等等.

项目源码

SpringBoot 教程: https://github.com/lixian13149999/spring-boot-learn

总结

使用 application.yml 文件可以很容易实现自定义参数配置, 在获取的时候也是相当的简便. 另外, 其提供的多环境配置也是团队开发者的福音, 不用再为 谁改了我的配置! 而苦恼!

有问题可以在留言区留言, 转发请注明出处, 谢谢