一、配置文件
Spring Boot使用一个全局的配置文件,文件名是固定的:application,文件类型可为properties和yml;
application.properties
application.yml
两种文件可任选其一,在配置文件中可修改Spring Boot自动配置的默认值;
二、YAML语言
YAML(YAML Ain’t Markup Language):YAML既是一种标记语言,又不是标记语言,很尴尬的解释~~,YAML文件以数据为中心,比json、xml等更适合做配置文件;
简单例子:
YAML文件:
server:
port: 8080
XML文件:
<server>
<port>8080</port>
</server>
1、基本语法
- 采用键值对的形式进行标识,但冒号后面必须加空格;
- 采用缩进来控制层级关系,左对齐的视为同一层级;
- 区分大小写;
如:
#k(键): (空格)v(值);
server:
port: 8080
path: http://blog.sina.com.cn/u/2853426941
2、值的写法
2.1、字面量(数字、字符串、布尔值等普通的值)
按上述语法直接书写即可,字符串默认不需要加引号(单引号和双引号);当然,非要加上也没有问题,但是要注意区分单引号和双引号,比如:
name: “zhangsan \n lisi” ——输出:zhangsan 换行 lisi
name: ‘zhangsan \n lisi’ ——输出:zhangsan \n lisi
即:
双引号会转译字符串里面的特殊字符;
单引号则不会转译特殊字符;
2.2、对象、集合
2.2.1、对象有两种写法:
1.如上面描述,采用缩进对齐的方式进行表示,如例1;
2.在一行中尽心表示,如例2;
例1:
server:
port: 8080
path: http://blog.sina.com.cn/u/2853426941
例2:
server: {port: 8080,path: http://blog.sina.com.cn/u/2853426941}
2.2.2、数组(List、Set):
用**- 值**的形式表示数组中的一个元素
names:
- lilei
- hanmeimei
- xiaoming
行内写法:
names: [lilei,hanmeimei,xiaoming]
三、配置文件值的注入
值的注入需要在需要注入的类上添加两个注解:
@Component
@ConfigurationProperties(prefix = "yamltest")
@Component:将这个类作为组件加入到容器中去,只有容器中的组件才能使用使用容器提供的@ConfigurationProperties功能;
@ConfigurationProperties:告诉SpringBoot将本类中的所有属性与配置文件中的相关配置进行关联;
prefix = “yamltest”:告诉SpringBoot将配置文件中的哪个名称下面的所有属性进行一一映射;默认从全局配置文件中获取值;
例:
yamltest:
name: wangmw
age: 17
map: {K1: V1,K2: V2}
list:
- cat
- car
- house
/**
* @ConfigurationProperties 用来将配置文件和类进行绑定
* prefix 用来指定使用的是配置文件中的哪个属性
* @Component 必须放在容器中才会生效
*
*/
@Component
@ConfigurationProperties(prefix = "yamltest")
public class YamlTest {
private String name;
private Integer age;
private Map<String, String> map;
private List<String> list;
1、@ConfigurationProperties和@Value的比较
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
2、@PropertySource、@ImportResource和@Bean
@PropertySource:同样是用于加载配置文件,由于@ConfigurationProperties默认加载的是全局配置文件,所以当我们写的配置属性过多时,将会分文件书写,此时,就需要将这些不是写在全局配置文件中的属性通过@PropertySource加载进去;
@ImportResource:加载的是Spring的默认配置文件,但是SpringBoot并不会自动加载Spring的配置文件,想让它被加载,必须使用@ImportResource将其与某个配置类相关联起来以达到被加载的目的;
@Bean:上面使用@ImportResource的方式进行加载配置文件的方式比较low,SpringBoot又提供了使用@Bean和@Configuration相结合的方式进行全注解式的加载,例:
@Configuration
public class SpringBootConfig {
@Bean
public TestService testService() {
System.out.println("加载了TestService这个类");
return new TestService();
}
}
测试:
@SpringBootTest
class SpringbootTestApplicationTests {
@Autowired
private ApplicationContext ioc;
@Test
void testService() {
// 输出为true
System.out.println(ioc.containsBean("testService"));
}
3、配置文件的占位符
随机数:
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
占位符获取之前配置的值,如果 没有可用:指定默认值:
person.name=wangmw${random.uuid}
person.age=${random.int}
person.birth=${person.year:2019}_出生
四、配置文件与加载环境
1.内部配置文件加载位置和顺序
springboot启动会扫描一下位置的application.properties或者application.yml文件作为springboot的默认配置文件;
-file:./config/
-file:./
-classpath:/config/
-classpath:/
优先级按上述顺序由高到低,高优先级配置会覆盖低优先级配置;
另外,当项目打包好之后,我们也可以通过启动命令行参数的方式指定配置文件的位置,所有的配置都是互补的,高优先级覆盖低优先级配置;
java -jar jar包位置 -spring.config.location=外部配置文件位置
2.外部配置文件加载顺序
2.1、命令行参数,所有的配置都可以再命令行上进行指定,多个配置用空格分开,例:
java -jar springboottest.jar --server.port=8099 --server.context-path=/aaa
2.2、来自java:comp/env的NDI属性
2.3、java系统属性(System.getProperties())
2.4、操作系统环境变量
2.5、RandomValuePropertySource配置的random.*属性值
3.总结配置文件
由jar包外向ar包内进行寻找:
优先加载带profile
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
再来加载不带profile
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
@Configuration注解类上的@PropertySource
通过SpringApplication.setDefaultProperties指定的默认属性
五、自动配置原理
我在学习过程中一直比较迷茫,我们在开发的时候要配置很多东西,这些配置的名称记不住怎么办?学习了自动配置原理之后才明白,每一种配置都可以深入到对应的类中进行查找有哪些配置名称,分别起到什么作用。
SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration;
该注解会给容器中导入一些组件,通过查看selectImports()方法可以知道Spring工厂加载类会扫描所有jar包类路径下META-INF/spring.factories,之后会将扫描到的这些文件的内容包装成properties对象,从properties中获取到EnableAutoConfiguration.class类对应的值,然后把他们添加到容器中。
精髓:
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpingBoot默认写好的自动配置类
3)、我们再来看这个自动配置类中到底配置了哪些组件;
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
xxxxAutoConfiguration:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;