SpringBoot学习日记
配置文件
默认配置文件名:
- application.properties
- application.yml
1、YAML
properties:
server.port : 8080
yml
server:
port:8080
基本语法:
- K: V 表示键值对(冒号后面有空格)
- 空格来控制层级关系,左对齐为同一层级
- 大小写敏感
值的写法:
- 字面量 普通的值(数字、字符串、布尔)k: V
字符串默认不用加引号,而且单引号和双引号不一样。双引号里面的特殊符号会被转义。
-
对象,map(属性和值)
K-V写法
Friend: lastName: zhansan age: 20
行内写法:
Friend: {lastName: zhansan,age: 18}
-
数组
写法1 - xxx
Pets: - cat - dog
##### 实践:
###### YML配置
People.class
// 必须为容器中的组件
@Component
// 配置文件哪个下面的所有属性 进行映射
@ConfigurationProperties(prefix = "people")
public class People {
private String name;
private Boolean gender;
private Integer age;
private Map<String,String> books;
private List<String> lists;
private Dog dog;
}
Dog.class
@Component
public class Dog {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
application.yml
people:
name: 'afsun'
gender: true
age: 24
books:
k1: v1
k2: v2
dog:
name: 小黑
lists:
- a1
- a2
- a3
- a4
- b1
pom.xml
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-configuration-processor</artifactId>
<optional> true </optional>
</dependency>
配置文件处理器:帮我们生成配置文件元数据,在配置文件件中可以生成提示
测试
package com.example.demo;
import com.example.demo.bean.People;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
- 单元测试
- 可以在测试期间,自动注入
*/
@RunWith(SpringRunner.class) // 指定使用Spring的单元测试而不是Junit
@SpringBootTest
public class DemoApplicationTests {
@Autowired
People p1 ;
@Test
public void contextLoads() {
System.out.println(p1);
}
}
###### properties方式
配置People
people.age=17
people.gender=true
people.name=afsun
people.books.key1 = v1
people.books..key2 = v2
people.lists=a,b,c
people.dog.name = 花花
输出:
People{name='afsun', gender=true, age=17, books={key1=v1, key2=v2}, lists=[a, b, c], dog=Dog{name='����'}}
###### @Value的使用
<bean class = "People" >
<!--${key}从环境变量、配置文件中获取、#{spEL} EL表达式-->
<property name="xxx" value="字面量/${key}/#{spel}" ></property>
</bean >
使用:
@Component
//@ConfigurationProperties(prefix = "people")
public class People {
@Value("#{11*22}")
private String name;
@Value("${people.gender}")
private Boolean gender;
private Integer age;
private Map<String,String> books;
private List<String> lists;
private Dog dog;
}
输入:
People{name='242', gender=true, age=null, books=null, lists=null, dog=null}
#### 2、@Value和@ConfigurationProperties区别
| | @ConfigurationProperties | @Value |
| :-----------------: | :----------------------: | :------------------: |
| 功能 | 批量注入配置文件中的属性 | 手动的,一个个的指定 |
| 松散绑定 | 支持 | 不支持 |
| SpEL | 不支持 | 支持 |
| JSR303数据校验 | 支持 | 不支持 |
| 复杂类型封装(map) | 支持 | 不支持 |
如果只是获取配置文件中的某个值那么久用@Value
如果专门写一个JavaBean的配置文件则用@ConfigurationProperties
JSR303数据校验
@Component
@Validated
@ConfigurationProperties(prefix = "people")
public class People {
@Email
private String name;
private Boolean gender;
private Integer age;
private Map<String,String> books;
private List<String> lists;
private Dog dog;
}
people.age=17
people.gender=true
people.name=afsun
people.books.key1 = v1
people.books..key2 = v2
people.lists=a,b,c
people.dog.name = gougou
输出
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'people' to com.example.demo.bean.People failed:
Property: people.name
Value: afsun
Origin: class path resource [application.properties]:4:13
Reason: 不是一个合法的电子邮件地址
修改:
����People
people.age=17
people.gender=true
people.name= ashuash12123@qq.com
people.books.key1 = v1
people.books..key2 = v2
people.lists=a,b,c
people.dog.name = gougou
输出正常
People{name='ashuash12123@qq.com', gender=true, age=17, books={key1=v1, key2=v2}, lists=[a, b, c], dog=Dog{name='gougou'}}
松散绑定:people.lastName = people.last-name*
#### 3、@PropertySource
告诉SpringBoot加载哪个配置文件。
@PropertySource(value={"classpath:people.properties"})
@component
@configurationProperties(prefix = "")
public class people {
.....
}
@ImportRsource
导入Spring的配置文件,让配置文件生效
SpringBoot没有Spring的配置文件,我们写的配置文件不能自动是被,如果需要Spring配置文件生效则需要用此注解标注在类上(主配置类)。
@ImportResource(locations = {""})、
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
SpringBoot推荐使用全注解的方式,使用配置来完成
// 注明为配置类
@configuration
public class MyConfig{
// 返回值添加到容器中,方法名为id名
@Bean
public BeanFactory getBeanFactory(){
/*
*/
}
}
#### 4、@ 配置文件占位符
##### 1、随机数
${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024.6454]}
##### 2、占位符
获取之前配置的值,如果没有值可以用:指定默认值
People
people.age=17
people.gender=true
随机数
people.name= ${radom.uuid}
people.books.key1 = v1
people.books..key2 = v2
people.lists=a,b,c
指示一个默认值
people.dog.name = ${people.name:afsun}_dog
#### 5、Profile
为了切换各种环境,生产环境、开发环境、测试环境
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
默认使用的是==application.properties==
##### 多文档
多文档:application-dev.properties、application-prod.properties....
application.properties
spring.profiles.active = dev
##### yml文档块
application.yml
server:
port:8083
spring:
profiles
active:dev --指定版本
------下面是文档块
---开发环境
server:
port:8083
spring:
profiles:dev
---生产环境
server:
port:8084
spring:
profiles:prod
---测试环境
server:
port:8085
spring:
profiles:test
##### 命令行方式选定
program arguments:--spring.profiles.active=xxx
JVM -Dspring.profiles.active = xxx
#### 6、配置文件加载位置
- -file:./config/
- -file:./
- -classpath:/config/
- -classpath:/
优先级从高到低的顺序,高优先级覆盖低优先级内容,SpringBoot4个位置的文件全部读取,**互补配置**
==spring.config.location== 指定默认的配置文件路径,运维时使用。
#### 7、外部配置加载顺序
可以从以下位置加载配置,符合上面的**互补配置**
- 命令行参数 `--server.port=xxx` 多个配置用空格分开
- jar包外部的application-{profile}.properties或application.yml(带spring.profile)(jar包外目录)
- jar包内部的application-{profile}.properties或application.yml(带spring.profile)
- jar包外部的application.properties或application.yml
- jar包内部的application.properties或application.yml
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultProperties指定
#### 8、自动配置原理
1. SpringBoot启动的时候加载主配置类,开启配置功能==@EnableAutoConfiguration==
2. @EnableAutoConfiguration
- 获取`META-INF/spring.factories` 中key为EnableAutoConfiguration.class的类名加入到容器中
- ```properties
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
- 自动配置类进行自动配置功能
@Configuration //为配置类 @EnableConfigurationProperties({HttpProperties.class}) //启用onfigurationProperties功能,指定类的,从配置文件中获取指定的数据,并把HttpProperties加入到容器中 @ConditionalOnWebApplication // Spring底层@Condition注解,判断当前应用是否是web应用 type = Type.SERVLET ) @ConditionalOnClass({CharacterEncodingFilter.class})// 判断当前项目是否有这个类 @ConditionalOnProperty( // 判断配置文件中是否存在某个配置:prefix。。。 prefix = "spring.http.encoding", value = {"enabled"}, matchIfMissing = true // 不存在,也是正确的 ) public class HttpEncodingAutoConfiguration { /** *通过有参构造器获得HttpProperties而HttpProperties映射了配置文件 */ public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); } @Bean @ConditionalOnMissingBean //当beanFactory没有该bean时 public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE)); return filter; } }
-
HttpProperties.class
所有在配置文件中能配置的属性都是在xxxProperties类中封装,配置文件能配置什么就可以参照某个功能对应的这个属性类。
@ConfigurationProperties( prefix = "spring.http" ) //根据"spring.http"可以在配置文件中,指定属性 public class HttpProperties {
根据当前的不同条件判断,决定这个配置类是否生效
xxxxAutoConfiguration:自动配置类
给容器添加相应的组件
xxxproperties类作为配置文件的映射类