springboot介绍、配置文件介绍、自动配置读取原理
- springBoot学习
- 代码说明
- 为什么java -jar springJar包后项目就可以启动
- 配置文件介绍
- 配置文件加载顺序
- 其他约定配置文件加载顺序
- profile配置文件加载
- 配置文件绑定类属性
- 通过@Value的方式进行属性注入
- 通过@ConfigurationProperties的方式进行属性注入
- 配置文件占位符
- 配置文件-属性注入:数据校验
- 通过@PropertySource可以引入外部properties配置文件
- Springboot自动配置底层原理
springBoot学习
依赖引入
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--打包好
帮我们把所有依赖的jar 统统放到jar文件里面的BOOT-INF\lib中
设置MANIFEST.MF设置了启动类 .JarLauncher:自定义类加载器加载所有的jar包,调用start-class。从而启动项目
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
代码说明
所有的springboot都必须继承spring-boot-starter-parent,通过里面的<artifactId>spring-boot-dependencies</artifactId>帮我们管理了依赖的版本
为什么引入了starter后其他依赖也就被引入了?
一个starter也就是启动器,内置了很多的依赖,就相当于一个聚合,引入一个starter也就都引入了
为什么java -jar springJar包后项目就可以启动
- 先打包
将打的jar包解压可以看到有个BOOT-INF的,里面还有个lib包这个lib包里存的就是项目依赖的其他jar包,叫fat-jar
META-INF中有个MANIFEST.MF文件,里面的Main-Class是所有的jar文件都有的,这个属性会自定义一个类加载器去加载fat-jar中的jar包。然后调用Start-Class去启动项目
配置文件介绍
springboot使用一个全局的配置文件 核心配置文件,配置文件名在 约定的情况下 名字是固定的就叫application
配置文件的作用:修改springboot自动配置的默认值;springboot在底层都给我们自动配置好了。比如端口号,springboot默认端口号8080,但是我们可以通过配置文件覆盖默认配置。
配置文件加载顺序
配置文件读取优先级:bootstrap.properties>bootstrap.yml>application.properties>application.yml 优先级大的会覆盖优先级小的
其他约定配置文件加载顺序
1、classpath根目录下
2、classpath根目录/config
3、项目根目录
如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录。如果是项目只有一个模块那么项目根目录 那就是当前模块的根目录
4、项目根目录 /config
如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录 /config。如果是项目只有一个模块那么项目根目录 那就是当前模块的根目录 /config
优先级由上到下,由低到高
profile配置文件加载
多环境配置配置文件
profile文件命名规则:application-名称.yml
- 在applicaction.yml中进行激活
spring:
profiles:
active: dev
配置文件绑定类属性
- 定义实体bean
@Data
@ToString
public class User {
private String username;
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
}
@Data
public class Address {
private Integer id;
private String detailAddress;
}
- 定义yml文件
user:
username: zzq
age: 25
通过@Value的方式进行属性注入
@Data
@ToString
@Component
public class User {
@Value("${user.username}")
private String username;
@Value("${user.age}")
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
}
- 测试
@SpringBootTest(classes = MyApplication.class)
public class Test {
@Autowired
private User user;
@org.junit.jupiter.api.Test
public void test(){
System.out.println(user);
}
}
通过@ConfigurationProperties的方式进行属性注入
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private String username;
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
}
- 测试
@SpringBootTest(classes = MyApplication.class)
public class Test {
@Autowired
private User user;
@org.junit.jupiter.api.Test
public void test(){
System.out.println(user);
}
}
@ConfigurationProperties:常用于bean属性和yml配置文件的绑定。prefix:可以指定配置文件中某一个节点,该节点中的子节点将自动和属性进行绑定
此外@ConfigurationProperties还支持松散绑定
@value和@ConfigurationProperties区别,最大的一个区别就是@ConfigurationProperties可以匹配多个,@value需要一个一个去匹配,比较麻烦
- 我们目前写yml文件没有提示,如果需要提示需要引入spring-boot-configuration-processor依赖
这个依赖会生成METE-INFO 元数据 用于提供idea自动提示配置文件的
<!--这个依赖会生成METE-INFO 元数据 用于提供idea自动提示配置文件的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<!--依赖不会传播 如果这是个父模块,子模块不会继承这个依赖-->
<optional>true</optional>
</dependency>
- 如果想要自动提示还需要修改idea相关配置
生成的元数据-用于自动提示
- 补充完剩余的属性
- list类型
hobbies:
- 唱歌
- 跳舞
- 打篮球
hobbies: [唱歌、跳舞、打篮球]
- map的类型
girl-friend:
18: 范冰冰
19: 刘亦菲
girl-friend: {18:范冰冰,19:刘亦菲}
- 嵌套对象
address:
id: 5
detailAddress: 6666
- 完整配置
user:
username: zzq
age: 123
birthday: 2020/01/01
hobbies:
- 唱歌
- 跳舞
- 打篮球
girl-friend: {18:范冰冰,19:刘亦菲}
address:
id: 6
detailAddress: 6666
配置文件占位符
可以通过${}来引用其他的配置项,这就是配置文件占位符,${}还可以引用springboot内置的一些属性,比如random.uuid
user:
username: zzq
age: 123
birthday: 2020/01/01
hobbies:
- 唱歌
- 跳舞
- 打篮球
girl-friend: {18:范冰冰,19:刘亦菲}
address:
id: 6
detailAddress: ${user.username}的家
id: ${random.int}
user:
username: zzq
age: 123
birthday: 2020/01/01
hobbies:
- 唱歌
- 跳舞
- 打篮球
girl-friend: {18:范冰冰,19:刘亦菲}
address:
id: ${random.int}
detailAddress: ${user.username}的家
配置文件-属性注入:数据校验
只支持@ConfigurationProperties,在使用的时候只需要加@Validated(支持对jsr-303数据校验)
- jsr-303数据校验
要支持对jsr-303数据校验还需要加入一个数据校验的场景启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 测试 -实体bean要测试的属性加上注解
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
@Validated
public class User {
private String username;
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
@NotNull
private Address address;
}
- 配置文件配置-去掉address不让能够注入
user:
username: zzq
age: 123
birthday: 2020/01/01
hobbies:
- 唱歌
- 跳舞
- 打篮球
girl-friend: {18:范冰冰,19:刘亦菲}
结果
通过@PropertySource可以引入外部properties配置文件
- properties配置
user.username=zzq
user.age=123
user.birthday=2020/02/06
user.hobbies=[跳舞、唱歌]
user.girlFriend.18=范冰冰
user.girlFriend.19=刘亦菲
user.address.id=5
user.address.detailAddress=上海
- 实体bean配置-@PropertySource(“classpath:data/user.properties”)
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
@Validated
@PropertySource("classpath:data/user.properties")
public class User {
private String username;
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
}