Spring Boot 2系列(二十): 配置文件加载及参数绑定

  Spring Boot提倡的是零配置,提供了强大的自动配置功能;只要装配了相应的功能,默认就会启用通用的配置(习惯优于配置)。

  但实际开发中,除了默认的配置外,根据需求难免需要定制配置文件;SpringBoot默认的配置文件application.properties会被自动加载,但定制的配置文件则需要我们自己手动加载。

  SpringBoot加载配置文件是将文件内容读取到Spring容器中,目的是为了给Spring容器中的上下文对象调用,达到一次加载,随处调用。

SpringBoot配置文件

  Spring Boot可以自动识别yml 和 properties两种文件,都是键值对(key/value)形式的配置;properties可直接使用注解@PropertySource加载自定义的文件;而yml文件需要从代码层面加载,不如前者方便,但yml面向对象的一种格式,更易于理解。

  默认的配置文件application.properties随项目的(Maven)创建而存在在src/main/resources目录中,会被自动加载。而我们自定义的配置文件,一般也放在些目录下,或在此目录建立子目录存放。

配置文件加载

公共配置文件

application.properties文件也称为公共配置文件,在SpringBoot启动时被自动加载,优先级最高。

1
2
3
4
server.port=80
server.servlet.context-path=/

book.name=spring boot

定制配置文件

定制配置文件xxx.properties文件,使用@PropertySource(value = "classpath:xxx.properties", encoding = "UTF-8")注解加载,作用在类上,基于一次加载,到处使用原则,因一份配置文件可能有多种类型参数,或有多个配置文件,一般会建一个配置类,将加载配置文件的注解统一放在该配置类上。value属性是个字符串数组,可以引入多个配置文件。

  1. mysql.properties
    1
    2
    3
    4
    #mysql.properties
    mysql.url=http://localhost:3306
    mysql.username=root
    mysql.password=123456
  2. PropertiesConfig.java
    1
    2
    3
    4
    5
    6
    7
    8
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;

    @Configuration
    @PropertySource(value = {"classpath:mysql.properties"}, encoding = "utf-8")
    public class PropertiesConfig {

    }

备注:默认编码是ISO 8859-1,故在默认的配置文件中使用中文时,会出现乱码,可以将中文转成Unicode编码或者使用yml配置格式(默认就支持utf-8), 或在配置java类上利用@PropertySource注解的 encoding 属性指定编码。

SpringBoot参数绑定

SpringBoot的参数绑定支持两种方式:

  1. 使用@Value("${key}")注解绑定每一项属性,每一项属性都要使用该注解。
  2. 使用@ConfigurationProperties(prefix="xxx")注解,匹配前辍,配置文件参数后辍与JavaBean的属性名一致,可实现批量自动绑定。

@Value绑定到属性

@Value注解是将每一项参数绑定到属性上。

1
2
@Value("${book.name}")
private String bookName;

属性前缀绑定到JavaBean

@ConfigurationProperties(prefix="xxx")注解作用在实体为上,将实体类注册到Spring容器,需要用到该实体类时,通过@Autowired注入到调用的类里。

  1. 实体类
    在类上添加@Component注解,将该类注册到到Spring容器,添加@PropertySource注解加载定制配置文件。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Component
    @PropertySource(value = {"classpath:mysql.properties"})
    @ConfigurationProperties(prefix="mysql")
    public class MysqlPro {

    private String url;
    private String account;
    private String password;

    //---set/get方法省略---
    }
  2. 定制配置文件:src/main/resources/mysql.properties
  3. 在调用实体类的业务类里面注入实体类Bean
    1
    2
    @Autowired
    private MysqlPro mysqlPro;

Array/List 接收参数

Spring Boot配置文件还支持数组类型的参数绑定,接收属情实体类里有一个 数组或List类型的 hobby 属性,如下配置:

1
2
3
4
5
6
# 方式一
user.hobby[0]=看电影
user.hobby[1]=旅游

# 方式二
user.hobby=看电影,旅游,运动

可以使用 List<String> 获取取hobby的值。

Map 接收参数

接收属情实体类里有一个 Map 类型的 person 属性,如下示例

1
2
3
4
5
6
7
8
9
# 方式一 
data.person.name=Tom
data.person.sex=boy
data.person.age=11

# 方式二
data.person[name]=Tom
data.person[sex]=boy
data.person[age]=11

@EnableConfigurationProperties

@ConfigurationProperties:作用在属性配置类上,可以通过prefix指定前缀。
@EnableConfigurationProperties:表示指定的类(JavaBean)注册为 Spring 容器的 Bean,并注入到本类 。

当调用类通过**@EnableConfigurationProperties来注入@ConfigurationProperties**注解的属性类时,属性类可以省略@Component@Configuration注解;调用类可以省略注入注解@Autowired,属性类作为调用方的一个属性参数来使用。

查看Spring Boot的自动配置源码,此方式使用也是比较多的。

  1. 属性类,通过前缀注入值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //省略@Component注解
    @ConfigurationProperties(prefix = "rest.server")
    public class RestServerProperties {

    private String url;

    public String getUrl() {
    return url;
    }

    public RestServerProperties setUrl(String url) {
    this.url = url;
    return this;
    }
    }
  2. 调用方
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Service
    @EnableConfigurationProperties({RestServerProperties.class})
    public class CallRemoteServiceImpl implements CallRemoteService {

    private static final Logger logger = LogManager.getLogger(CallRemoteServiceImpl.class);

    //省略@Autowired注解
    private RestServerProperties restServerProperties;

    //------方法--------------

    }

调用使用@ConfigurationProperties注解的JavaBean时,在调用类上使用@EnableConfigurationProperties({xxxxProperties.class})注解指定该JavaBean需要注册为Spring容器的Bean,即在调用前声明注册为Bean,这样在JavaBean上就不需要使用@Component@Configuration注解。

生成随机数

Spring Boot的属性配置文件中可以通过${random}来产生 int 值、 long 值或者 string 字符串,来支持属性的随机值。

1
2
3
4
5
6
7
8
9
10
//随机字符串
blog.value=${random.value}
//随机int
blog.number=${random.int}
//随机long
blog.bignumber=${random.long}
//10以内的随机数
blog.test1=${random.int(10)}
//1-20的随机数
blog.test2=${random.int[1,20]}

Spring Boot 2系列(二十): 配置文件加载及参数绑定

http://blog.gxitsky.com/2018/06/25/SpringBoot-20-paramBindFromProperties/

作者

光星

发布于

2018-06-25

更新于

2022-06-17

许可协议

评论