02-SpringBoot配置文件
一、配置文件的使用SpringBoot使用一个全局的配置文件核心配置文件配置文件名在约定的情况下是固定的配置文件的作用修改SpringBoot自动配置的默认值SpringBoot在底层都给我们自动配置好application.propertiesapplication.yml二、两种配置文件的格式在springboot框架中resource文件夹里可以存放配置的文件有两种properties和yml。1、application.properties的用法扁平的k/v格式。key/valueserver.port8081 server.servlet.context-path/tuling2、application.yml的用法树型结构 可读性更强 值前面一定要有空格server: port: 8088 servlet: context-path: /tuling三、配置文件的加载顺序2.3.x官方没有具体说明实测以properties为准2.4.0如果指定了多个位置则后一个位置可以覆盖前一个位置的值。2.4.4建议整个应用程序使用一种格式如果您的配置文件的格式.properties和.yml都位于同一位置则以properties优先级为准。3.1.5以.properties为准。四、其它约定配置文件加载顺序springboot启动还会扫描以下位置的application.properties或者application.yml文件作为Spring Boot的默认配置文件低1、classpath的根目录下的2、classpath的根config/3、项目根目录如果当前项目是继承/耦合 关系maven项目的话项目根目录父maven项目的根目录4、项目根目录/comfig5、直接子目录/config高优先级由低到高高优先级的配置会覆盖低优先级的配置互补配置五、profile配置文件加载Profile的意思是配置对于应用程序来说不同的环境要不同的配置。SpringBoot框架提供了多profile的管理功能我们可以使用profile功能来区分不同环境的配置。1.Spring官方给出的语法规则是application-{properties}.properties(.yaml/.yml)。2.如果需要创建自定义的properties文件时可以用application-xxx-properties的命名方式。六、配置文件值注入1.vaulepackage com.example.hello.beans; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; //可以通过Value SPEL表达式来直接绑定springbooot配置文件中的值 Component public class User { Value(${user.username}) private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday birthday; } public ListString getHobbies() { return hobbies; } public void setHobbies(ListString hobbies) { this.hobbies hobbies; } public MapInteger, String getGirlFriend() { return girlFriend; } public void setGirlFriend(MapInteger, String girlFriend) { this.girlFriend girlFriend; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address address; } private Integer age; private Date birthday; private ListString hobbies; private MapInteger,String girlFriend; private Address address; Override public String toString() { return User{ username username \ , age age , birthday birthday , hobbies hobbies , girlFriend girlFriend , address address }; } }package com.example.hello.beans; import org.springframework.stereotype.Component; Component public class Address { public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc desc; } private Integer id; private String desc; }application.propertiesuser.username123 server.port8080运行结果2.ConfigurationProperties(prefixuser)package com.example.hello.beans; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; Component ConfigurationProperties(prefix user) public class User { // Value(${user.username}) private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday birthday; } public ListString getHobbies() { return hobbies; } public void setHobbies(ListString hobbies) { this.hobbies hobbies; } public MapInteger, String getGirlFriend() { return girlFriend; } public void setGirlFriend(MapInteger, String girlFriend) { this.girlFriend girlFriend; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address address; } // Value(${user.age}) private Integer age; DateTimeFormat(pattern yyyy-MM-dd) private Date birthday; private ListString hobbies; private MapInteger,String girlFriend; private Address address; Override public String toString() { return User{ username username \ , age age , birthday birthday , hobbies hobbies , girlFriend girlFriend , address address }; } }user: username: 徐庶 age: 25 birthday: 1999-01-01 hobbies: - 读书 - 游泳 - 编程 girlFriend: 1: 貂蝉 2: 小乔 address: id: 1 desc: 河南省郑州市 server: port: 8080运行结果User{username徐庶, age25, birthdayFri Jan 01 00:00:00 CST 1999, hobbies[读书, 游泳, 编程], girlFriend{1貂蝉, 2小乔}, addressAddress{id1, desc河南省郑州市}}松散绑定user: USERNAME: 徐庶 user: userName: 徐庶 user user-name 徐庶 user: user_name: 徐庶 以上四种命名是可以自动绑定bean属性 User.username3.ConfigurationProperties对比Value 获取值JSR303数据校验二者都支持4.配置文件占位符ConfigurationProperties不支持SPEL表达式只支持两种占位符。1.对属性值的引用占位符2.对属性随机值的引用补SPEL表达式分类核心内容示例表达式说明与用途表达式的样子写在#{...}里#{3 5}这是 SpEL 的标准语法一眼就能认出来区别于属性占位符${...}用于读取外部配置文件。支持的数据类型字面量、数字、布尔、字符串、集合等#{Hello}#{1 0}#{1,2,3}支持常见的 Java 数据类型还可以直接写集合比如 List 和 Map。能做什么运算算术、比较、逻辑、三元、正则匹配#{1 2 * 3}#{score 60}#{age 18 ? 成人 : 未成年}几乎覆盖了所有常见的运算逻辑可以替代很多简单的 Java 判断代码。如何访问数据操作对象属性、调用方法、访问容器 Bean#{user.name}#{user.getName()}#{userService.findById(1)}这是 SpEL 最核心的能力可以灵活地读取或调用程序中的任何对象。用前缀就能直接拿到 Spring 容器里的 Bean。特殊的变量系统属性、方法参数、安全上下文等#{systemProperties[java.version]}#{#param1}#{authentication.name}内置了很多常用对象让你能方便地获取环境信息或当前请求的上下文。参数用#参数名来引用。处理空值安全的导航操作符#{user?.address?.city ?: 未知}?.会优雅地处理空指针如果中间任何一个对象是null就不会报错直接返回null或指定的默认值。主要应用场景注解赋值、权限校验、条件化配置Value(#{...})PreAuthorize(#{...})ConditionalOnExpression(...)这三个注解见右侧覆盖了 90% 以上的日常使用场景让你的配置和代码变得非常灵活。5.属性注入---数据校验!-- 数据校验-- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependencyBinding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under user to com.example.hello.beans.User failed: Property: user.address Value: null Reason: 不能为null七、总结自定义配置文件绑定值