配置文件详解:yml多环境、配置优先级、参数绑定
配置文件详解yml多环境、配置优先级、参数绑定配置文件就像是项目的控制面板旋钮拧到哪程序就怎么跑。拧错了轻则乱码重则线上事故。这篇把配置那点事儿一次说透。一、properties vs yml对比SpringBoot默认支持两种配置文件格式.properties和.ymlYAML。1.1 格式对比properties格式扁平结构server.port8080 server.servlet.context-path/api spring.datasource.urljdbc:mysql://localhost:3306/test spring.datasource.usernameroot spring.datasource.password123456yml格式树状层级server:port:8080servlet:context-path:/apispring:datasource:url:jdbc:mysql://localhost:3306/testusername:rootpassword:123456对比项propertiesyml层级表达扁平靠点号缩进树状结构可读性一般好层次清晰支持列表不直观支持-语法数据类型全是字符串有类型推断重复前缀多少实际开发中yml是主流本文也以yml为主。二、yml基础语法2.1 核心规则缩进用空格不用Tab这是最容易踩的坑缩进层级表示从属关系同级要对齐键值对用冒号空格分隔key: value冒号后面必须有空格大小写敏感2.2 常见数据结构键值对name:张三age:25列表数组server:port:8080interests:-编程-游戏-睡觉也可以行内写法interests:[编程,游戏,睡觉]嵌套对象person:name:张三age:25address:city:北京street:朝阳区三、多环境配置3.1 为什么要多环境开发用本地数据库测试用测试库生产用线上库。总不能每次发布手动改配置吧多环境配置就是解决这个问题的。3.2 配置文件拆分src/main/resources/ ├── application.yml # 主配置公共配置放这里 ├── application-dev.yml # 开发环境 ├── application-test.yml # 测试环境 └── application-prod.yml # 生产环境application.yml主配置server:port:8080spring:profiles:active:dev# 激活dev环境application-dev.ymlspring:datasource:url:jdbc:mysql://localhost:3306/dev_dbusername:dev_userpassword:dev_passlogging:level:root:DEBUGapplication-prod.ymlserver:port:80spring:datasource:url:jdbc:mysql://192.168.1.100:3306/prod_dbusername:prod_userpassword:复杂的密码logging:level:root:WARN3.3 激活指定环境方式一配置文件中激活如上spring.profiles.active: dev方式二命令行参数激活最常用java-jarmyapp.jar--spring.profiles.activeprod方式三环境变量激活exportSPRING_PROFILES_ACTIVEprodjava-jarmyapp.jar四、配置优先级SpringBoot配置来源非常多优先级从高到低优先级配置来源说明1命令行参数--server.port90902SPRING_APPLICATION_JSON环境变量中的JSON配置3ServletConfig/ServletContext初始化参数4JNDI环境变量5Java系统属性System.getProperties()6操作系统环境变量7RandomValuePropertySource随机值8jar包外的application-{profile}.yml外部配置文件9jar包内的application-{profile}.yml内部配置文件10jar包外的application.yml11jar包内的application.yml12PropertySource注解代码中指定的配置文件13默认值SpringBoot硬编码的默认值记忆口诀外部 内部命令行 文件带profile 不带profile。实际开发中最常用的是命令行参数覆盖yml文件配置用于线上临时调整参数。五、参数绑定方式5.1 Value注解最简单直接的方式适合少量参数RestControllerpublicclassHelloController{Value(${server.port})privateintport;Value(${app.name:默认应用名})// 冒号后是默认值privateStringappName;}5.2 ConfigurationProperties适合批量绑定将一组配置映射到Java对象yml配置app:name:我的博客系统version:1.0.0author:黑漂技术佬配置类ComponentConfigurationProperties(prefixapp)Data// Lombok注解自动生成getter/setterpublicclassAppProperties{privateStringname;privateStringversion;privateStringauthor;}使用时直接注入AutowiredprivateAppPropertiesappProperties;5.3 Value vs ConfigurationProperties对比对比项ValueConfigurationProperties使用场景单个简单值一组相关配置松散绑定不支持支持app-name能绑到appNameSpEL表达式支持不支持JSR303校验不支持支持元数据生成无有IDEA有提示松散绑定示例yml里写app-name、app_name、appName都能绑定到appName字段。5.4 配置类加JSR303校验ComponentConfigurationProperties(prefixapp)DataValidated// 开启校验publicclassAppProperties{NotBlank(message应用名不能为空)privateStringname;Pattern(regexp^\\d\\.\\d\\.\\d$,message版本号格式应为x.x.x)privateStringversion;Email(message邮箱格式不对)privateStringemail;}配置不合法时项目启动直接报错把问题拦在启动阶段。六、常见yml配置陷阱6.1 缩进错误# 错误Tab和空格混用spring:\tdatasource:url:xxxyml不允许Tab缩进一律用空格。IDEA里设置将Tab转为空格可以根治这个问题。6.2 中文乱码properties文件默认用ISO-8859-1编码写中文必乱码。yml默认UTF-8没这个问题。如果必须用propertiesIDEA设置Settings → Editor → File Encodings → Default encoding for properties files: UTF-8同时勾选Transparent native-to-ascii conversion。6.3 引号问题# 字符串一般不需要引号name:张三# 但包含特殊字符时需要引号description:hello: world# 包含冒号用引号password:123456# 纯数字想当字符串用引号# 双引号会转义单引号不转义path1:D:\new\folder# \n会被当成换行path2:D:\new\folder# 原样输出6.4 布尔值陷阱# 下面两个含义不同enabled:true# 布尔值trueenabled:true# 字符串trueyml有类型推断true/false/yes/no会被识别为布尔值。绑定到String字段时如果不想被转类型加引号。