SpringBoot之配置
Posted milkywaygalaxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot之配置相关的知识,希望对你有一定的参考价值。
回顾:
配置文件
① 两种全局配置文件(文件名是固定的)
配置文件放在src/main/resources目录或者类路径/config下
application.properties(优先级高)
application.yml / application.yaml
配置文件的作用: 修改SpringBoot自动配置的默认值
② YAML
yml / yaml是YAML(YAML Ain‘t Markup Language)语言的文件, YAML以数据为中心, 比json/xml等更适合做配置文件.
实例:
YAML的基本语法
- 使用缩进表示层级关系
- 缩进时不允许使用tab键, 只允许使用空格
- 缩进的空格数目不受限制, 只要相同层级的元素在左侧对齐即可
- 大小写敏感
YAML支持的三种数据结构
- 对象 / Map(属性和值): 键值对的集合
普通写法:
friends:
lastName: zhangsan
age: 20
行内写法:
friends: {lastName: zhangsan,age: 20}
- 数组: 一组按次序排列的值
用- 值表示数组中的一个元素
普通写法:
pets:
- cat
- pig
- dog
行内写法:
pets: [cat,pig,dog]
- 字面量(普通的值, 如: 数字 字符串 布尔): 单个的 / 不可再分的值
直接写: 字符串默认不用加单引号或双引号
"": 双引号不会转义字符串里面的特殊字符, 特殊字符会作为其本身的意义输出
如: name: ‘zhangsan lisi‘ ==> 代表为 zhangsan 换行 lisi
‘‘: 单引号会转义字符串里面的特殊字符, 特殊字符不会作为其本身的意义输出(特殊字符最终只是一个普通的字符串)
如: name: ‘zhangsan lisi‘ ==> 代表为 zhangsan lisi
③ 实例测试
实体类:
Person:
Dog:
配置文件(application.yml):
将配置文件中的每个值映射到属性中:
在Person类上加入以下两个注解:
注: 可以先导入配置文件处理器, 这样在编写配置文件时会有相应的提示
测试:
测试结果:
配置文件(application.properties):
测试结果:
另一种获取配置文件的值的方式(@Value("字面量 / ${key} / #{SpEL表达式}")):
测试结果:
@ConfigurationProperties和@Value的区别:
@ConfigurationProperties | @Value | |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持(如: first-name和firstName相同) | 不支持(只支持first-name) |
SpEL表达式 | 不支持 | 支持(如: #{2.3*10}) |
JSR303数据校验(在类上使用@Validated注解) |
支持(如: 在某个字段上使用@Email注解, 则该字段必须为邮箱格式才正确, 否则报错) |
不支持 |
复杂类型封装 | 支持(如: 取Map或List或对象中的值) | 不支持 |
数据校验格式:
小结:
如果只是在某个业务逻辑中需要获取一下配置文件中的某项或某几项值, 则使用@Value注解; 如果专门编写了一个javaBean来和配置文件进行映射, 此时则需要@ConfigurationProperties注解.
从非全局配置文件中获取值进行映射的注解:
1) @ PropertySource(value={"配置文件的路径",...})
将之前的属性值都移到person.properties文件中, 测试能否将值注入Person类下的属性内.
2) @ImportResource: 导入Spring的配置的文件, 让配置文件的内容生效
beans.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="helloService" class="com.idea.springbott.service.HelloService"></bean> </beans>
HelloService:
SpringBoot推荐给容器中添加组件的方式: 全注解方式
① 配置类<====>配置文件
② @Bean注解: 类同于配置文件中的<bean></bean>标签, 意为将方法的返回值添加到容器中
MyConfig配置类:
配置文件占位符:
① 随机数
${random.value} / ${random.int} / ${random.long} / ${random.int(10)} / ${random.int[1024, 65536]}
② 占位符获取之前的属性值, 如果没有则可以指定默认值
属性配置:
profile标识: 动态切换, 以便适应不同的环境(开发环境 / 测试环境 / 生产环境等)
激活方式
1) spring.profiles.active=[具体的profile的名称]
2) 命令行: 打包成jar, 利用控制台方式启动(java -jar [部署包的名称] --spring.profiles.active=[profile的名称])
或者在idea中的Edit Configurations中进行设置也是属于命令行的一种方式
3) 虚拟机参数(VM options): -Dspring.profiles.active=[profile的名称]
① .properties文件的切换方式
在主配置文件编写的时候, 文件名可以是 application-[profile标识].properties/yml
如: application-dev.properties(表示开发环境) / application-prod.properties(表示生产环境)
默认情况下使用application.properties / application.yml主配置文件, 如果需要切换环境配置文件, 需要在主配置文件里面激活该需要切换的配置文件, 如: spring.profiles.active=[profile标识]
② .yml文件的切换方式(文档块)
内部配置文件的加载顺序:
4个存放位置: 按照优先级从高到低排列, 高优先级的配置覆盖低优先级的配置
① file: /config/ ==> 当前项目下的config文件夹下 优先级最高
② file: / ==> 当前项目下 优先级第二
③ classpath: /config/ ==> classpath下的config文件夹下 优先级第三
④ classpath: / ==> classpath下 优先级第四
SpringBoot会从这四个位置全部加载主配置文件从而互补配置
通过spring.config.location来改变默认的配置文件的位置
① 打包项目
② 使用命令行参数的形式, 在启动项目的时候指定配置文件的新位置, 指定的配置文件会和默认加载的配置文件共同起作用形成互补配置
外部配置文件的加载顺序:
SpringBoot也可以从以下位置加载配置文件, 优先级由高到低, 高优先级的配置会覆盖低优先级的配置, 所有的配置会形成互补配置.
① 命令行参数
java -jar [jar包名] --server.port=8089 / 其他命令也行(多个参数用空格隔开).
优先加载带spring.profiles.active, 并且由外部向内部加载(外部的优先级比内部的高)
② jar包外部的application-[profile的名称].properties / .yml(带spring.profiles.active)配置文件
③ jar包内部的application-[profile的名称].properties / .yml(带spring.profiles.active)配置文件
再加载不带spring.profile, 并且由外部向内部加载(外部的优先级比内部的高)
④ jar包外部application-[profile的名称].properties / .yml(不带spring.profiles.active)配置文件
⑤ jar包内部application-[profile的名称].properties / .yml(不带spring.profiles.active)配置文件
⑥ @Configuration注解类上的@PropertySource指定配置文件
自动配置原理:
配置文件能配置的属性
1) SpringBoot启动的时候加载主配置类, 开启了自动配置功能(注解: @EnableAutoConfiguration)
2) @EnableAutoConfiguration的作用:
利用@Import({EnableAutoConfigurationImportSelector.class})给容器中导入一些组件
selectImports(AnnotationMetadata annotationMetadata) ==> List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); //获取候选项的配置
① SpringFactoriesLoader.loadFactoryNames()
② classLoader.getResources("META-INF/spring.factories") //扫描所有jar包类路径下的META-INF/spring.factories
把扫描到的内容封装成properties对象, 并从中取出EnableAutoConfiguration.class类对应的值, 最后把它们添加进容器中.
每一个xxxAutoConfiguration都是容器中的一个组件, 都加入到容器中, 用他们来做自动配置.
3) 每一个自动配置类进行自动配置功能
4) 所有在配置文件中能配置的属性都是在xxxProperties类中封装着
HttpEncodingProperties: 该类上标注了@ConfigurationProperties(prefix = "spring.http.encoding")注解
该注解从配置文件中获取指定的值和bean的属性进行绑定
5) 举例: HttpEncodingAutoConfiguration(http编码的自动配置)
@Configuration //这是一个配置类
@EnableConfigurationProperties({HttpEncodingProperties.class}) //启动指定类的ConfigurationProperties的功能; 将配置文件中对应的值和HttpEncodingProperties绑定起来;
@ConditionalOnWebApplication //Spring底层有@Conditional注解, 根据不同的条件, 如果满足指定的条件, 整个配置类才会生效.(判断当前应用是否是web应用, 如果是: 当前配置类生效)
@ConditionalOnClass({CharacterEncodingFilter.class}) //判断当前项目是否有CharacterEncodingFilter类
CharacterEncodingFilter: 是SpringMVC中进行乱码解决的过滤器
@ConditionalOnProperty(prefix = "spring.http.encoding", value = {"enabled"}, matchIfMissing = true) //判断配置文件中是否存
在某个配置, 即: spring.http.encoding.enabled; matchIfMissing = true: 如果文件不存在, 判断也是成立的(也就是说, 即使不配
置spring.http.encoding.enabled=true, 也是默认生效的)
private final HttpEncodingProperties properties; //该属性已经和SpringBoot的配置文件进行映射了 //只有一个有参构造器的情况下, 参数的值就会从容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean //给容器中添加一个组件, 这个组件的某些值(例如 编码)需要从properties中获取 @ConditionalOnMissingBean({CharacterEncodingFilter.class}) public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }
所以, HttpEncodingAutoConfiguration这个类的意义就是根据当前不同的条件进行判断, 决定这个配置类是否生效.
一旦这个配置类生效, 这个配置类就会给容器中添加各种组件, 这些组件的属性是从对应的properties类中获取的, 而这些类里面每一个属性又是和配置文件绑定的.
总结:
① SpringBoot启动会加载大量的自动配置类
② 查看需要的功能有没有SpringBoot默认写好的自动配置类
③ 如果有, 这个配置类配置了哪些组件(需要则注入即可, 无需再配置), 如果没有, 则需要自己写配置类
④ 给容器中的自动配置类添加组件的时候, 会从properties类中获取某些属性, 就可以在配置文件中指定这些属性的值(跟配置文件绑定了)
附:
由于自动配置类必须在一定条件下才能生效, 所以可以通过在配置文件中启用debug=true属性, 让控制台打印自动配置报告, 即能很方便知道具体哪些配置类生效哪些配置类不生效.
以上是关于SpringBoot之配置的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot中级教程之SpringBoot自定义配置