SpringBoot 允许你外部化你的配置,以便你可以在不同的环境中使用相同的应用程序代码。你可以使用 properties文件、YAML 文件、环境变量和命令行参数来外部化配置。可以使用 @Value
注解直接将属性值注入到 Bean 里面,也可以通过 @ConfigurationProperties
将属性绑定到结构化对象中。
配置注入
@Value 注入
SpringBoot 会默认加载类路径下的 application.properties
配置,延续上一篇中的例子,我们在配置文件中添加上允许登录的用户名及密码。
application.properties
配置:
1 | user.name = 13632672222 |
用户 Controller:
1 |
|
测试效果如下,配置成功:
@ConfigurationProperties 注入
系统用户一般不会只存在一个,如果需要配置多个用户,很显示上面的注入方式是无法满足需求的,那就需要使用到 @ConfigurationProperties
注解了。
application.properties
配置:
1 | sys.users[0].username = 13632672222 |
Properties
映射对象:
1 | "sys") (prefix = |
Mapping
方法:
1 |
|
调用用户查询接口,获取用户信息如下,可以看到用户的年龄也自动转成了所需要的 int 类型:
1.3. 参数合法性校验
开发人员一般是无法管理生产环境的,应用的部署及维护是运维人员的工作,如果运维小伙伴一不小心漏掉了某个参数怎么办?虽然部署文档可以在一定程度上规避这些问题,但仍然存在一定的隐患,为了尽量减少此类问题,我们可以给外部配置加上相应的校验规则。
要求必须配置用户,且所有用户年龄都需要在20岁以上:
1 | "sys") (prefix = |
如果上面的配置不做任何更新,那么就会得到启动异常:
1 | Description: |
YAML 配置
YAML 是 JSON 的超集,它是一种非常方便的数据格式,用于指定带有层次结构的配置数据。当你的类路径里面带有 snakeyaml 库的时候,SpringApplication
类会自动支持 YAML 来替代 properties 配置。使用 application.yml
替换 application.properties
如下:
1 | sys: |
在 User
类里面添加一个新的字段 nickName
,并在配置文件中添加相应的配置:
1 | sys: |
当我们再次调用查询用户接口时,会返回如下报文:
1 | { |
如果仔细观察配置文件的话,会发现两个用户配置 nickName
的方式是不一致的,一个是 nickName
,一个是 nick-name
,但它们两个都可以成功,这是因为 SpringBoot 将环境属性绑定到 @ConfigurationProperties
定义 Bean 时,使用了一些比较宽松的规则,主要包括下面几种变形:
属性 | 标注 |
---|---|
users.nickName | 标准的驼峰语法 |
users.nick-name | 虚线符号,推荐在 properties 及 yml 文件中使用 |
users.nick_name | 下划线符号,properties 及 yml 里面的一种替代格式 |
USERS_NICK_NAME | 大写格式化,推荐在环境变量中使用 |
配置分离
开发的过程中,可能存在很多套环境,开发、集成、测试等,每个环境的配置都不一样,想要更好地维护这些环境,需要将相关的配置文件隔离开来,SpringBoot 里面提供了两种方式来帮我们完成这项任务。
Profile 的使用
对每一套环境创建一个对应的配置文件,如果开发使用 dev,集成使用 int,那么就可以创建两个配置文件,分别命名成 applicationj-dev.yml
与 application-int.yml
,通过在 application.yml
里面声明需要激活的配置文件变更系统配置。
application-dev.yml
配置:
1 | sys: |
application-int.yml
配置:
1 | sys: |
application.yml
配置:
1 | spring: |
最终效果如下:
指定配置路径
application.yml
文件一般是存放在包内,那就存在着一个问题,生产配置无法由开发人员管理,项目打包也就不会将其打包到应用程序里面去。要解决这个问题,需要使用到 spring.config.location
这个配置项,由于这个配置项会被用来决定配置文件的加载路径,所以,它需要在环境属性中定义,如:系统变量、命令行参数等。
去除 application.yml
文件,直接指定配置文件路径,得到效果如下:
注意:当使用 spring.config.location
时,spring.profiles.active
配置项将会失效,也就是在这种模式下是不区分 profile 的,示例中只是为了让读者看的更加明白,所以使用的不同的文件名而已。
配置加密
推荐一个比较好的加密工具(jasypt),下面我们来看一下该工具的用法:
首先,需要添加 Jar 包的依赖项配置:
1 | "com.github.ulisesbocchio:jasypt-spring-boot-starter:1.12" |
其次,配置解密需要用到的算法及密钥:
1 | jasypt: |
然后,使用上面配置的算法及密钥对需要加密的数据进行加密,使用 jasypt-1.9.2.jar
对明文 root 进行加密:
1 | java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=funda algorithm=PBEWithMD5AndDES |
该命令需要在 jasypt-1.9.2.jar
所在的路径下执行,得到输出结果如下:
1 | ----ENVIRONMENT----------------- |
最后,将加密后的结果配置到配置文件中:
1 | spring: |
加密后的配置值需要使用 ENC 进行包括,这样 jasypt 才会识别出该值是一个密文,需要进行解密操作。
项目的 github 地址:https://github.com/qchery/funda