springboot官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/
一、配置文件
springboot使用一个全局的配置文件,配置文件名是固定的。
- application.properties
- application.yml
配置文件的使用:
- 修改springboot自动配置的默认值
- springboot在底层都给我们自动配置好
yml是标记语言。比xml更优秀,以数据为中心,简洁,更适合做配置文件。
例如:
xml:
<server>
<port>8081</port>
</server>
yml:
server:
port: 8081
二、yml语法
1、基本语法
key:空格value 表示一堆键值对(空格必须有);
以空格的缩进控制层级关系,对齐即是同一层级。
server:
port: 8081
path: /hello
2、值的写法
字面量: 普通值(数字、字符串、布尔)
k:v : 字面直接写
字符串默认不用加上单引号或者双引号
"" : 双引号内部的特殊字符不会转义,特殊字符会作为自身想表达的意思
name: "winds \n wins" 输出: winds 换行 wins
' ':单引号,会转义字符,特殊字符最终变成普通字符串数据。
name: 'winds \n wins' 输出: winds \n wins
对象、map(属性和值) (键值对)
k:v : 在下一行写对象的属性和值的关系,空格缩进
friends:
lastName: winds
age: 23
行内写法:
friends: {lastName: winds, age: 18}
数组(List, Set):
用-值表示数组中的一个元素:
pets:
- dog
- cat
- pig
行内写法:
pets: {dog, cat, pig}
三、配置文件值注入
properties
person.age=18
person.dog.name=kele
person.dog.age=1
person.last-name=winds
person.list=1,2,3
person.map.winds=12
person.map.cloud=13
yml
server:
port: 8084
person:
lastName: winds
age: 22
map: {name: 11,money: 22}
list:
- 1
- 2
- 3
dog:
name: kele
age: 1
组件:
package com.example.yml;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
*
* 将配置文件中配置的每一个属性映射到组件中
*
* @ConfigurationProperties:告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定。
*
* prefix = "person":配置文件中以person开头的所有属性一一映射
* 如果没有指定配置文件,默认是读取程序的全局配置文件,也就是application*.properties/yml之类的文件信息。
*/
@Component
@Data
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Map map;
private Dog dog;
private List list;
}
pom.xml
导入配置文件处理器
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Value获取值和@configurationProperties获取值比较
@configurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定 | 支持 例如lastName last-name | 不支持 |
spEL | 不支持 | 支持 |
校验 | 支持 | 不支持 |
Map | 支持 | 不支持 |
List | 支持 | 不支持,但是可以用表达式函数解析 |
@Value
@Component
@Data
public class Person {
@Value("${person.last-name}")
private String lastName;
@Value("#{11*3+2}")
private Integer age;
@Value("#{${map}}")
private Map map;
private Dog dog;
@Value("#{'${person.list}'.split(',')}")
private List list;
}
配置文件对应的值必须是字符串,通过表达式的方式解析,例如:
yml
map: "{name: 11,money: 22}"
list: 1,2,3
properties不适合。
所有别想了,还是使用yml 配上@configurationProperties,人家还支持@valiated 校验,参数校验美滋滋,适合整个javabean赋值。平时只是单项设置值,倒是可以使用@Value更方便
@PropertySource(value={“classpath:person.properties”})
指定读取person.properties文件的配置信息
@ImportResource 导入spring的配置文件,让配置内容生效,例如xml中的bean实例化。
springboot中没有Spring的配置文件,所以如果我们自己写入的话,就需要把@ImportResource标注在配置类中。
测试用例:
@RunWith(SpringRunner.class)
@SpringBootTest
public class YmlApplicationTests {
@Autowired
Person person;
@Autowired
ApplicationContext applicationContext;
@Test
public void contain(){
boolean result = applicationContext.containsBean("helloService");
System.out.println("result:"+result);
}
}
ApplicationContext程序上下文,可以获取出很多信息,例如bean有没有实例化成功。
xml这种配置bean的方式都是在spring 中使用到的,太古老了,springboot其实不推荐,更推荐下面这种。
SpringBoot推荐使用@Configuration配置类的方式代替spring的配置文件。
package com.example.yml.config;
import com.example.yml.service.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfigs {
/**
* 方法名就是bean的名字
* @return
*/
@Bean
HelloService helloServiceDemo(){
return new HelloService();
}
}
配置文件占位符
- 随机值:
person.age=${random.int}
person.dog.name=${random.value}
person.dog.age=1
person.last-name=winds
person.list=${random.long}, ${random.uuid},${random.long(1024,65535)}
person.map.winds=12
person.map.cloud=13
- 可以指定默认值
person.dog.name=${person.hello:winddd}
四、profile
多profile文件:
- application-dev.properties
- application-prod.properties
默认是使用application.properties,通过spring.profiles.active=dev 进行设置读取哪个环境的配置。
application.yml
server:
port: 8084
spring:
profiles:
active: prod #指定激活的环境
---
server:
port: 8085
spring:
profiles: dev
--- #---分割文档,本yml被分成三部分
server:
port: 8086
spring:
profiles: prod #指定环境
- 配置文件中设置环境
修改默认端口:-Dserver.port=8009
- 在程序参数中设置运行命令行
- 运行jar包的时候用命令行
java -jar xxx.jar --spring.profiles.active=dev
- 虚拟机参数设置
-Dspring.profiles.active=dev
五、配置文件加载位置
springboot启动会扫描一下位置的application。properties或者application.yml文件作为其默认配置文件
优先级由高到低:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
上述所有文件都会被程序加载,优先级高的内容会覆盖低优先级配置内容,并且是互补的!!!
最高优先级的是,我们在启动jar包的时候,或者运维发布系统里面设置配置文件,能够实现无需重新打包,直接新增新的配置信息,也是满足互补原则。
例如:
java -jar xxx.jar --spring.config.location=/user/winds/application.properties
server.servlet.context-path 可以设置项目路径,已经替代了server.context-path
六、外部配置加载顺序
springboot也可以在一下位置加载配置,优先级由高到低,互补原则。
主要使用的几种方式:
- 命令行输入,上述所示,优先级最高
java -jar xxx.jar -server.port=8090 --server.servlet.context-path=/winds
多个配置空格隔开:–配置项=值
jar包外 向 jar包内进行寻找:
优先加载带profile
- jar包外部的application-{profile}.properties或者application.yml 中带spring.profile的配置文件
- jar包内部的application-{profile}.properties或者application.yml 中带spring.profile的配置文件
优先加载带profile
- jar包外部的application-{profile}.properties或者application.yml 中不带spring.profile的配置文件
- jar包内部的application-{profile}.properties或者application.yml 中不带spring.profile的配置文件
七、自动配置原理
自动配置原理:
- springboot加载主配置类,开启了自动配置功能@EnableAutoConfiguration
- @EnableAutoConfiguration作用:
1.利用@Import(AutoConfigurationImportSelector.class) AutoConfigurationImportSelector中的selectImports方法导入组件。 2.获取自动配置的META路径下的信息: AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); 扫描路路径:META-INF/spring-autoconfigure-metadata.properties loadMetadata会把配置信息properties包装成AutoConfigurationMetadata返回。 扫描:META-INF/spring.factories getAutoConfigurationEntry()方法中的实现去获取META-INF/spring.factories下的自动配置类名 然后进行去重、排序、过滤。 3.最后把这些符合条件的自动配置类添加到容器中。
例子:
@Configuration //表示这个是个配置类,也可以给容器添加组件
@ConditionalOnClass({ MBeanExporter.class }) //判断当前项目又没这个类
@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true",
matchIfMissing = true) //判断配置文件中是都存在这个配置 spring.jmx.enabled; 如果不存在,判断也是成立。即使我们配置文件中不配置spring.jmx.enabled=true, matchIfMissing = true默认生效
public class JmxAutoConfiguration implements EnvironmentAware, BeanFactoryAware {
@Bean 最后添加到组件中
精髓:
- springboot启动加载大量自动配置类
- 看我们需要功能有没有springboot写好默认的自动配置类
- 我们再看这个自动配置类中到底配置类哪些组件。
- 给容器中自动配置类添加到容器中成为组件时,会从配置文件properties中获取某些属性,我们就能在配置文件中设置这些属性值。
自动配置类必须是满足一定条件下才能生效。
就像上述例子中,各种@conditional 就是判断是否满足创建条件的。
通过在配置文件中添加debug=true就能够知道哪些自动配置类是生效的。
控制台: