概述
目标:掌握配置文件、加载顺序、配置原理。
配置文件
- SpringBoot使用一个全局的配置文件,配置文件名称固定。
- application.properties
- application.yml
- 配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot启动是在底层都给我自动配置好。
- 配置文件存放在src/main/resources目录下或者 类路径/config下
- yml是YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,比json、xml等更适合做配置文件。
- http://www.yaml.org/ 参考语法规范
YAML语法
YAML基本语法
- key:(空格)value:表示一对键值对,空格必须要有。
- 使用缩进表示层级关系。
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只有相同层级的元素左侧对齐即可。
- 大小写敏感。
YAML支持的三种数据结构
- 对象:键值对的集合。
friends:
lastName: zhangsan
age: 20
行内写法:
friends: {lastName: zhangsan, age: 20}
- 数组:一组按次序排列的值。
用 – 值的方式表数组中的元素。
pets:
- cat
- dog
- pig
行内写法:
pets: [cat,dog,pig]
- 字面量:单个的、不可再分的值。
字符串默认不用加上单引号或者双引号。
“”双引号:不会转义字符串中的特殊字符,特殊字符会作为本身想表达的意思。
比如:name: “zhangsan \n list”,输出结果:zhangsan
list
”单引号:会转义特殊字符,特殊字符最终只是一个普通的字符串数据。
比如:name: ‘zhangsan \n list’,输出结果:zhangsan \n list
YAML配置文件值获取
示例:新建Person类和Dog类,演示如何获取,字面量、数组、对象、map的配置信息
/**
* 想获取配置信息,必须是容器中的bean,其实和bean初始化逻辑一种,配置文件的信息其实就是属性填充
* @ConfigurationProperties 告诉Spring对象的值从配置文件中获取,prefix前缀表示从配置文件中哪个配置项下面获取属性值
* 自动必须要有get/set方法,否则无法完成属性填充(其实属性就是字段+get/set方法)
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age;
private String address;
private List<Object> like;
private Map<String, Object> maps;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Object> getLike() {
return like;
}
public void setLike(List<Object> like) {
this.like = like;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", like=" + like +
", maps=" + maps +
", dog=" + dog +
'}';
}
}
public class Dog {
private String name;
private int age;
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- 添加配置处理器,可以在编写Yaml文件绑定对象是有相应的提示
<!--导入配置处理器后,配置文件进行绑定就会有智能提示功能,没其他作用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 测试
@SpringBootTest注解,用于单元测试,可以字段装配对象,无需手动context.getBean()获取bean对象。
@SpringBootTest
class PracticeApplicationTests {
@Autowired
private Person person;
@Test
public void testYAML() {
System.out.println(person);
}
}
properties配置
从properties中获取配置值
配置信息获取与yaml获取基本一致,只是在properties中写法不一样,其它完全一样。
- 配置信息
person.name=wangwu
person.address=中国北京
person.age=18
person.like=旅游,电影
person.maps.k1=唱歌
person.maps.k2=跳舞
person.dog.name=小狗
person.dog.age=2
解决乱码问题
产生乱码的原因
idea使用的utf8编码,但是properties使用的ASCII编码,因此需要在idea中把properties文件设置成utf8格式,同时转换成assii格式。
@Value
普通变量获取配置信息
可以通过@Value注解在字段上给字段赋值,@Value与bean标签中的value配置作用一致,因此用法也一致。
示例:
@Component
public class Person {
/**
* 1. @Value类似于bean标签中的value配置;
* 2. bean中的value可以配置:字面量;${key}获取环境变量、配置文件中的key值,#{SpEl}spring的EL表达式;
* 因此@Value也可以配置上面的三种值。
* 3. @Value获取配置信息,可以不写get/set方法。
* <bean id = "person" class="xxxxx">
* <property name="address" value="xxx"></property>
* </bean>
*/
@Value("小明")
private String name;
@Value("#{11*2}")
private int age;
@Value("${person.address}")
private String address;
private List<Object> like;
private Map<String, Object> maps;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Object> getLike() {
return like;
}
public void setLike(List<Object> like) {
this.like = like;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", like=" + like +
", maps=" + maps +
", dog=" + dog +
'}';
}
}
@Value注解配置默认值
@Value在注解模式下读取配置文件注入属性值
示例:
@Value("${name}")
private String name;
但是,如果配置文件中没有设置name的值,spring在启动的时候会报错。这时需要给name配置默认值,代码如下:
@Value("${name:bob}")
private String name;
除了String类型外,其他类型也可配置默认值:
@Value("${age:18}")
private int age;
@Value注入列表或者数组
可以使用split()方法在一行中注入“列表”。
配置如下:
config.properties
server.name=hydra,zeus
server.id=100,102,103
AppConfigTest.java
package com.mkyong.analyzer.test;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@PropertySource(value="classpath:config.properties")
public class AppConfigTest {
@Value("#{'${server.name}'.split(',')}")
private List<String> servers;
@Value("#{'${server.id}'.split(',')}")
private List<Integer> serverId;
//To resolve ${} in @Value
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
注意如果配置项已逗号分隔,无需使用split方法,spring默认支持逗号的分隔。
可以指定默认值,下面的3种写法Spring都是支持的。
@Value("#{'${server.id:127.0.0.1,192.168.1.18}'.split(',')}")
private List<String> serverId;
@Value("${server.id:127.0.0.1,192.168.1.18}")
private List<String> serverId;
@Value("${server.id:127.0.0.1,192.168.1.18}")
private String[] serverId;
@Value给静态变量注入值
- @Value不能直接给静态变量赋值,即使编译不报错,但是结果赋值不成功。
@Value("${fastdfs.cache.redis.expireTime:86400}")
public static int EXPIRE_TIME;
- 静态变量赋值,@Value注解需要放在方法上
类上加上@Component注解,方法名(例如setExpireTime,方法名可以随便写,通常以set开头)和参数名(例如expireTime,参数名也可以随便写),如下所示:
/**
* 缓存过期时间,单位秒
*/
public static int EXPIRE_TIME;
/**
*
* @param expireTime 过期时间
*/
@Value("${fastdfs.cache.redis.expireTime:86400}")
public void setExpireTime(int expireTime) {
EXPIRE_TIME = expireTime;
}
@ConfigurationProperties与@Value的区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 可以批量注入配置文件中的属性 | 只能一个个的指定 |
松散语法绑定(对象中的小驼峰命名与配置文件中-命令相互转换,比如:字段:lastName,可以在配置文件中写出last-name/last_name) | 支持 | 不支持 |
SPEL表达式(Spring 表达式) | 不支持 | 支持 |
JSR303数据校验(Java Specification Requests,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。) | 支持 | 不支持 |
复杂类型获取(对象、Map、数组) | 支持 | 不支持 |
配置文件yaml或者properties格式都行。
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@PropertySource与@ImportResource
@PropertySource
用来加载指定的配置文件
/**
* 想获取配置信息,必须是容器中的bean,其实和bean初始化逻辑一种,配置文件的信息其实就是属性填充
* @ConfigurationProperties
* 1. 告诉Spring对象的值从配置文件中获取,prefix前缀表示从配置文件中哪个配置项下面获取属性值;
* 2. 用来读取全局配置文件(resources/application.yml,resource/application.properties),
* 如果全局配置文件信息太多,就需要按场景拆分,为了能够读取到配置需要使用@PropertySource注解指定配置文件
* @PropertySource 指定具体需要映射的配置文件,可以通过数组一次性指定多个。
*
*/
@Component
@PropertySource(value = "classpath:person.properties")
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
private String name;
private int age;
private String address;
private List<Object> like;
private Map<String, Object> maps;
private Dog dog;
...
}
@ImportResource
用来导入Spring的配置文件,让配置文件里面的内容生效。
SpringBoot里面没有Spring的配置文件,我们自己编写的配置文件是不能识别的,
想让Spring的配置文件生效,加载进来,我们需要通过@ImportResource显示的标注在一个配置类上。
@ImportResource(locations = {"classpath:bean.xml"})
@SpringBootApplication
public class PracticeApplication {
public static void main(String[] args) {
SpringApplication.run(PracticeApplication.class, args);
}
}
// 测试类
@SpringBootTest
class PracticeApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testBean() {
System.out.println(applicationContext.containsBean("helloService"));
}
}
- bean的配置文件
<?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.practice.springboot.practice.service.HelloService"></bean>
</beans>
SpringBoot推荐使用全注解配置
SpringBoot推荐给容器添加组件的方式是使用全注解的方式,而不是上面的@ImportResource导入xml配置的方式。
- 使用@Configuration配置来代替Spring配置文件;
- 使用@Bean给容器中添加组件;
/**
* @Configuaration:类似Spring中的XML配置,可以让我们直接使用java编码的方式去配置Spring的组件。
* @Bean:
* 1. 类似于Spring中xml配置文件的bean标签;作用是把方法返回的对象添加到Spring容器中;
* 2. 添加到容器中的对象的默认id值是方法名称。
*
*/
@Configuration
public class MyAppConfig {
@Bean
public HelloService helloSer() {
System.out.println("helloSer 对象创建");
return new HelloService();
}
}
// 测试类
@SpringBootTest
class PracticeApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testBean() {
System.out.println(applicationContext.containsBean("helloSer"));
}
}
- 测试结果
2021-04-09 17:13:58.119 INFO 13188 --- [ main] c.p.s.practice.PracticeApplicationTests : Starting PracticeApplicationTests using Java 1.8.0_181 on DESKTOP-OTR8LPB with PID 13188 (started by asus in D:\work_space\practiceSpringboot)
2021-04-09 17:13:58.129 INFO 13188 --- [ main] c.p.s.practice.PracticeApplicationTests : No active profile set, falling back to default profiles: default
helloSer 对象创建
2021-04-09 17:14:02.855 INFO 13188 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-04-09 17:14:03.530 INFO 13188 --- [ main] c.p.s.practice.PracticeApplicationTests : Started PracticeApplicationTests in 6.417 seconds (JVM running for 9.251)
true
2021-04-09 17:14:04.203 INFO 13188 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
配置文件占位符
随机数占位符
可以在配置文件application.properties或者其他properties的配置文件中使用随机数占位符
person.name=zhangsan${random.uuid}
// 比如下面这些类型
${random.value}、${random.int}、${random.long}、${random.int(10)}、${random.int[1024,65536]}
占位符代表的值
如果占位符之前配置的值,就是代表配置的值,如果之前没有配置就是占位符key,还可以使用:指定默认值(在占位符没有配置值的情况下,取默认值)
person.like=${person.hello:like}_movie
案例
- application.properties 配置文件配置信息
person.name=zhangsan${random.uuid}
person.age=18
person.address=china_${person.name}
person.like=${person.hello:like}_movie
获取的值如下:
2021-04-10 12:47:45.736 INFO 1164 --- [ main] com.springboot.test.demo.TestConfig : Started TestConfig in 1.738 seconds (JVM running for 3.678)
Person{name='zhangsanaeb3e706-2834-4c9f-a209-2f26ef371f71', address='china_zhangsan1c4cfdf7-771d-4122-b304-524da3574e9d', age=18, like='like_movie'}
Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境。
多profile文件
我们在配置文件(默认配置文件:application.properties)编写的时候,文件名可以是:application-{profile}.properties/yml
例如:application-dev.properties、application-prod.properties
默认配置文件:application.properties
激活指定profile
- 配置文件方式激活
在默认配置文件中指定spring.profiles.active=xxx,就可以激活相应的profile配置文件。
比如:spring.profiles.active=prod
- 命令行激活(优先级最高)
启动时添加 –spring.profiles.active=xxx
命令行激活方式优先级高于配置文件/虚拟机方式,就是如果命令行、配置文件、虚拟机同时配置了,命令行的集合方式生效
比如:
java -jar practiceSpringboot.jar –spring.profiles.active=dev
YAML文件多文档块模式
通过在yml文件中添加 — 来分割不同的文档,使用spring.profiles来定义不同文档的名称,如下所示:
配置文件加载位置
默认加载位置
spring boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件。
- file:./config/ 项目目录下的config文件夹下
比如:与src同一个目录的config文件就是项目目录下的config文件夹。
- file:./ 项目目录下
- classpath:/config/ 类路径下的config文件夹下,比如src/main/resource/config/
- classpath:/ 类路径下,比如src/main/resource/
- 上面的优先级从高到低排序(1的优先级大于2的优先级…),所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容;比如classpath:/config/ 下面的配置会覆盖 classpath:/ 下面的相同配置。
- 我们也可以通过配置spring.config.location来改变默认配置。
- springboot会从这四个位置全部加载主配置文件,互补配置(把4个地方的配置不同的key合在一起,相同的key高优先级覆盖低优先级)。
指定加载位置
我们还可以通过在命令行传入:spring.config.location来改变默认的配置文件位置,优先级最高,相同的key会被覆盖。
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置。
示例如下:
外部配置加载顺序
SpringBoot也可以从以下位置加载配置;
顺序优先级由高到低,相同的key高优先级覆盖低优先级,所有配置形成互补配置。
- 命令行参数。
可以在命令行指定所有默认配置(多个配置用空格隔开),优先级最高。
java -jar spring-boot.SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
- 来自java:comp/env的JNDI属性。
- java系统属性(System.getProperties())。
- 操作系统环境变量。
- RandomValuePropertySource配置的random.*属性值。
- jar包外部的application-{profile}.properties或application.yml{带spring.profile}配置文件。
- jar包内部的application-{profile}.properties或application.yml{带spring.profile}配置文件。
- jar包外部的application.properties或者application.yml(不带spring.profile)配置文件。
示例:
在jar包外部编写配置文件application.properties与jar在同一个目录下,jar包启动时会优先加载外部application.properties的配置。
# 无需指定配置文件,位置放置正确会自动加载外部的配置文件
java -jar spring-boot.SNAPSHOT.jar
- jar包内部的application.properties或者application.yml(不带spring.profile)配置文件。
- @Configuration注解类上的 @PropertySource
- 通过SpringApplication.setDefaultProperties指定的默认属性。
自动配置原理
目标:配置文件到的写什么?怎么写?自动配置原理是什么?
所有配置项的属性信息
参考:
springboot配置项信息
自动配置原理
- Springboot启动的时候加载主配置类,开启了自动配置功能,自动配置功能开启由@EnableAutoConfiguration注解决定;
- @EnableAutoConfiguration作用
- 利用@EnableAutoConfigurationImportSelector给容器中导入一些组件。
- 查看selectImports()方法的内容:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
- 获取候选的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
// 扫描所有Jar包类路径下 META-INF/spring.factories,把扫描到的这些文件的内容包装成properties对象
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
// 从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把它们添加到容器中。
(List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
- springboot启动时根据配置的@EnableAutoConfiguration注解,将类路径下所有的 META-INF/spring.factories里面配置的EnableAutoConfiguration的值加入到容器中;
- 每一个下面的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用它们来做自动配置。
# 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,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
- 每一个自动配置类进行自动配置功能;
- 以HttpEncodingAutoConfiguration为例接受自动配置原理;
// 表示这是一个配置类,与以前编写的配置文件一样,也可以给容器中添加组件
@Configuration(
proxyBeanMethods = false
)
// 启动指定类的ConfigurationProperties功能,将配置文件中对于的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到spring的ioc容器中。
@EnableConfigurationProperties({ServerProperties.class})
// Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置才会生效;
// 判断当前应用是否是web应用,如果是当前配置类生效。
@ConditionalOnWebApplication(
type = Type.SERVLET
)
// 判断当前项目中有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})
// 判断配置文件中是否存在某个配置 server.servlet.encodind.enabled;
// matchIfMissing = true如果不存在判断也是成立的;
// 总结:即使我们配置文件中不配置server.servlet.encoding.enabled=true,也是默认生效的
@ConditionalOnProperty(
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
// 它已经和springboot的配置文件映射了
private final Encoding properties;
// 只有一个有参构造器的情况下,参数的值就会从容器中获取。
public HttpEncodingAutoConfiguration(ServerProperties properties) {
this.properties = properties.getServlet().getEncoding();
}
// 给容器添加一个组件,这个组件的某些值需要从properties中获取。
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
return filter;
}
根据当前不同的条件判断,决定这个配置类是否生效。
一旦这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的。
- 所有配置文件中能配置的属性都是在xxxProperties类中封装着
配置文件能配置什么就可以参照某个功能对应的这个属性类。
// 从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(
prefix = "server",
ignoreUnknownFields = true
)
public class ServerProperties {
private Integer port;
总结
- SpringBoot启动会加载大量的自动配置类
- 我们看需要的功能有没有springboot默认写好的自动配置类;
- 我们再来看这个自动配置类到底配置了哪些组件(只要我们要用的组件有,我们就不需要再来配置了)
- 给容器中自动配置类添加组件的时候,会从xxxProperties类中获取某些属性,我们就可以在配置文件中指定这些属性的值。
- 相关自动配置类的作用
xxxAutoConfigration:自动配置类,给容器中添加组件;
xxxProperties:封装配置文件中相关属性;
@Conditional与自动配置报告
@Conditional注解
必须是@Conditional指定的条件成立,才给容器添加组件,配置类里面的内容才会生效。
自动配置必须在一定条件下才能生效。
自动配置报告
- 有哪些自动配置类
spring-boot-autoconfigure\2.4.4\spring-boot-autoconfigure-2.4.4.jar!\META-INF\spring.factories
文件下的org.springframework.boot.autoconfigure.EnableAutoConfiguration键对应的值。 - 哪些配置类会生效
如何判断哪些配置类是否生效呢?
- 可以通过看代码,看@Conditionalxxx条件是否成立,如下:
@ConditionalOnMissingClass({"org.aspectj.weaver.Advice"})
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"proxy-target-class"},
havingValue = "true",
matchIfMissing = true
)
static class ClassProxyingConfiguration {
ClassProxyingConfiguration(BeanFactory beanFactory) {
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
}
}
============================
CONDITIONS EVALUATION REPORT
============================
# 启用的自动配置
Positive matches:
-----------------
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
AopAutoConfiguration.ClassProxyingConfiguration matched:
- @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)
DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' (OnClassCondition)
- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
# 没启用的自动配置类
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)
ArtemisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
BatchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
......
我们可以通过查看打印报告的方式快速确定哪些配置类被启用,可以很方便的对项目进行配置。
参考
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100355.html