springboot官方文档(2.2.7.RELEASE):https://docs.spring.io/spring-boot/docs/2.2.7.RELEASE/reference/htmlsingle/
springboot中文文档(2.0.1.RELEASE):https://www.breakyizhan.com/springboot/3028.html
一、SpringBoot入门
SpringBoot是Spring团队在2014年伴随Spring4.0版本开发出的一个框架。J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大,使得SpringBoot的诞生。SpringBoot是为了简化Spring应用开发,约定大于配置,去繁化简。
简化Spring应用开发的框架、整个Spring的大整合、J2EE开发的一站式解决方案。
SpringBoot的优点
微服务
微服务是一种架构风格(服务微化),在2014年由martin fowler提出,他认为一个应用应该是一组小型服务,可以通过HTTP的方式进行互通,并且每个功能元素最终都是一个可独立替换和独立升级的软件单元。
"微服务"文档:https://martinfowler.com/articles/microservices.html
"微服务"文档中文版:https://mp.weixin.qq.com/s?__biz=MjM5MjEwNTEzOQ==&mid=401500724&idx=1&sn=4e42fa2ffcd5732ae044fe6a387a1cc3#rd
HelloWorld
浏览器发送hello请求,服务器接收请求并处理,响应HelloWorld字符串。
- 创建一个maven项目
- 导入springboot依赖
<!--父项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- 导入插件,此插件可以将应用打包成一个可执行的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 编写一个主程序,启动springboot应用
package com.angenin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //标注一个主程序类,说明这是一个SpringBoot应用
public class HelloWorldMainApplication {
public static void main(String[] args) {
//spring应用启动(第一个参数为主程序类,第二个参数为main方法的参数)
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
- 编写相关的Controller、Service
package com.angenin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "HelloWorld";
}
}
- 运行主程序
- 在浏览器输入:
http://localhost:8080
(成功访问页面)
- 输入
http://localhost:8080/hello
(成功访问并返回HelloWorld)
- 停止项目,打包项目
- 使用终端进入jar所在的目录,
java -jar 包名
运行项目。
- 重新在浏览器输入
http://localhost:8080/hello
探究HelloWorld
1. pom.xml
父项目
<!--父项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
按住ctrl键点击spring-boot-starter-parent,发现这个父项目里还依赖着个父项目。
按住ctrl键点击spring-boot-dependencies,发现这个父项目里写着依赖的版本。(真正管理SpringBoot应用里的所有依赖版本,SpringBoot的版本仲裁中心)
所以,以后到入依赖不需要写版本号,因为使用的版本已经提前指定了。(而没有在dependencies里面管理的依赖,还是需要写版本号)
导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web:
- spring-boot-starter:SpringBoot场景启动器(帮我们导入了Web模块正常运行所依赖的组件)
SpringBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目里引入这些starter,相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器。
2. 主程序类(主入口类)
@SpringBootApplication //标注一个主程序类,说明这是一个SpringBoot应用
public class HelloWorldMainApplication {
public static void main(String[] args) {
//spring应用启动(第一个参数为主程序类,第二个参数为main方法的参数)
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
@SpringBootApplication
:SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。
查看@SpringBootApplication注解发现组合注解。
@SpringBootConfiguration
:SpringBoot的配置类
标注在某个类上表示这是一个SpringBoot的配置类@Configuration
:@SpringBootConfiguration注解上标注着@Configuration表示这是一个配置类。@Component
:@Configuration上也标注着@Component表示是一个组件。
@EnableAutoConfiguration
:开启自动配置功能
以前我们需要配置的东西,SpringBoot帮我们自动配置,@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效。@AutoConfigurationPackage
:自动配置包@Import({Registrar.class})
:Spring的底层注解@Import,给容器中导入一个组件,导入的组件由Registrar.class,将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到spring容器中。
@Import({AutoConfigurationImportSelector.class})
:给容器中导入AutoConfigurationImportSelector类,这个类为导入哪些组件的选择器。
将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。
会给容器中导入非常多的自动配置类(XXXAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。
有了自动配置类,免去我们手动写配置注入功能组件等的工作。SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类帮我们做了。
J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-2.3.0.RELEASE.jar里。
使用SpringInitializer快速创建SpringBoot应用
- 新建项目
继续下一步,创建,然后SpringBoot就会联网为我们快速创建一个SpringBoot应用。
生成的这些文件目前没什么用,可以先删除。
默认生成的SpringBoot项目
- 主程序已经生成好了,我们只需要写我们的业务逻辑
- resources目录
- static:保存所有的静态资源(js、css、images)
- templates:保存所有的模板页面(SpringBoot默认jar包使用嵌入式的tomcat,默认不支持jsp页面),但可以使用模板引擎(freemarker、thymeleaf)
- application.properties:SpringBoot应用的配置文件,可以修改一些默认配置
- 新建一个HelloController。
package com.angenin.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@RestController //效果和@Controller+@ResponseBody一样(Controller下的所有方法都是@ResponseBody,如果是对象转为json数据)
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "HelloWorldQuick";
}
}
在主配置类里启动SpringBoot应用。
然后在浏览器里输入http://localhost:8080/hello
二、SpringBoot配置
1. 配置文件
在类路径下有application.properties
或application.yml
,SpringBoot都会把它当成全局的配置文件,配置文件名是固定的。
配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好了。
YAML
- YAML(YAML Ain’t a Markup Language):
YAML A Markup Language:是一种标记语言
YAML isn’t Markup Language:不是一种标记语言 - 标记语言:
以前的配置文件;大多都使用的是xxx.xml文件
YAML:以数据为中心,比json、xml等更适合做配置文件 - 配置例子:
YAML:
server:
port: 8081
XML:
<server>
<port>8081</port>
</server>
YAML的语法
1. 基本语法
k: (空格) v 表示一对键值对(空格必须有)
以空格的缩进来控制层级关系,只要是左对齐的一列数据,都是同一个层级的。
server:
port: 8081
path: /hello
属性和值也是大小写敏感。
2. 值的写法
-
字面量:普通的值(数字、字符串、布尔)
k: (空格) v 字面值直接写
字符串默认不用加单引号或双引号
“”(双引号):不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思。
例:name: “zhangsan \n lisi” 输出zhangsan (换行) lisi
‘’(单引号):会转义特殊字符,特殊字符最终只是一个普通的字符串数据。
例:name: ‘zhangsan \n lisi’ 输出zhangsan \n lisi -
对象、Map(属性和值)(键值对)
k: (空格) v 对象还是k: v的方式,在下一行来写对象的属性和值的关系(注意缩进)
例:
friends:
lastname: zhangsan
age: 22
行内写法:
friends: {lastname: zhangsan,age: 22}
- 数组(List、Set)
用 - (空格) 值表示数组中的一个元素
例:
pets:
- cat
- dog
- pig
行内写法
pets: [cat,dog,pig]
2. @ConfigurationProperties配置文件值注入
yml配置文件数据注入
快速新建一个名为spring-boot-02-config的SpringBoot项目
在resources里添加一个名为application.yml文件
server:
port: 8081
person:
lastName: zhangsan
age: 18
boss: true
birth: 2020/01/01
maps: {k1: v1,k2: v2}
lists:
- lisi
- zhaoliu
dog:
name: xiaohuang
age: 2
在java/com/angenin/springboot下新建一个bean包,在包下新建两个类Dog和Person。
package com.angenin.springboot.bean;
public class Dog {
private String name;
private Integer 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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package com.angenin.springboot.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
//将配置文件中配置的每一个属性的值,映射到这个组件中
//@ConfigurationProperties 告诉SpringBoot将本类的所有属性和配置文件中相关的配置进行绑定(默认从全局配置文件中获取数据)
// prefix = "person" 配置文件中哪个下面的所有属性进行一一映射
@ConfigurationProperties(prefix = "person")
@Component //如果不加上@Component,@ConfigurationProperties会标红,这是因为@ConfigurationProperties注解是容器提供的功能,没有添加到容器的组件不能使用
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
这时候会出现“Spring Boot配置注解执行器没有配置”。
需要引入依赖
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
在test/java/com/angenin/springboot下的SpringBoot02ConfigApplicationTests进行测试。
/**
* SpringBoot单元测试
* 可以在测试期间很方便的类似编码一样进行自动注入等容器的功能
*/
@SpringBootTest
class SpringBoot02ConfigApplicationTests {
@Autowired
Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
运行期间如果卡在这
请强制退出idea,重新进入并添加依赖:
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
成功把application.yml中person数据注入
properties配置文件数据注入
注释掉yml文件中的person数据,在properties文件中写入
person.last-name=张三
person.age=19
person.birth=2020/01/01
person.boss=true
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=小黄
person.dog.age=2
运行测试类发现,虽然成功注入,但是输入的中文出现乱码的情况。
解决方法:
如果重新运行后,还是乱码,可以试试先把properties文件的person数据注释掉,然后运行yml中的数据,然后再运行properties文件的数据,还是不行的话重新启动idea,多试几次就可以了 。
3. 使用@Value注入数据
@Value支持字面量、${key}从环境变量或配置文件中获取值、#{SpEL}
例:
注释掉Person类上的@ConfigurationProperties,在Person类的属性上加上@Value。
//测试三种写法
@Value("${person.last-name}")
private String lastName;
@Value("#{10*2}")
private Integer age;
@Value("true")
private Boolean boss;
@Value与@ConfigurationProperties的区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验(@Validated) | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
松散语法:lastName与last-name、last_name相同
使用选择:
如果只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value。
如果专门编写一个javabean和配置文件进行映射,使用@ConfigurationProperties。
4. @PropertySource和@ImportResource
@PropertySource
:加载指定的配置文件
例:
在resources下新建一个person.properties配置文件。
@PropertySource(value = {"classpath:person.properties"}) //指定加载的配置文件
@ConfigurationProperties(prefix = "person") //默认从全局配置文件中获取值
@Component
public class Person {...}
@ImportResource
:导入SpringBoot的配置文件,让配置文件中的内容生效。
例:
在com/angenin/springboot/service新建一个HelloService类。
在resources下新建一个beans.xml的spring配置文件。
<?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.angenin.springboot.service.HelloService"></bean>
</beans>
在测试类中添加
@Autowired
ApplicationContext ioc;
@Test
public void testHelloService(){
//判断容器中是否包含指定的组件
boolean b = ioc.containsBean("helloService");
System.out.println(b);
}
运行结果为:false
说明创建配置文件并在里面注册,但是配置文件却没运行,如果想要配置文件运行,需要在主配置类上加上@ImportResource注解。
@ImportResource(value = {"classpath:beans.xml"}) //导入配置文件使其生效
@SpringBootApplication
public class SpringBoot02ConfigApplication {...}
重新运行的结果为:true
SpringBoot推荐使用全注解的方式添加组件
例:
注释掉主配置类的@ImportResource
在com/angenin/springboot/config中添加,名为MyAppConfig.java类
package com.angenin.springboot.config;
import com.angenin.springboot.service.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //指明当前类是一个配置类(代替spring的xml配置文件)
public class MyAppConfig {
@Bean //将方法的返回值添加到容器中,默认id为方法名(代替xml配置文件中的<bean>)
public HelloService helloService(){
System.out.println("配置类往容器中添加HelloService组件...");
return new HelloService();
}
}
重新运行测试类的testHelloService方法,结果为true
不需要在主配置类上加注解,只要在类上加@Configuration注解表明是配置类即可。
5. 配置文件占位符
例:
person.last-name=张三${random.uuid} #随机数uuid
person.age=${random.int} #随机整数
person.birth=2020/01/01
person.boss=true
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=${person.last-name}的小黄
person.dog.age=${person.hello:3} #如果没有person.hello,取默认值3
运行结果:
Person{lastName='张三9d6d3b11-98ac-4752-87d6-fce3ed6f0171', age=-1814115186, boss=true, birth=Wed Jan 01 00:00:00 CST 2020, maps={k1=v1, k2=v2}, lists=[a, b, c], dog=Dog{name='张三b79bd0fc-35a9-4c8e-89a0-1da2fedd6b36的小黄', age=3}}
6. Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境。
-
多Profile文件形式(properties文件):
编写不同环境的主配置文件时,文件名可以是application-{profile}.properties。{profile}为环境名
默认使用application.properties的配置文件。 -
多Profile文档块模式(yml文件):
---
为分隔文档块,下面是三个文档块,对应不同的端口
server:
port: 8081
spring:
profiles:
active: dev #指定激活的环境
---
server:
port: 8082
spring:
profiles: dev
---
server:
port: 8083
spring:
profiles: prod
- 激活方式:
在resources下新建application-dev.properties和application-prod.properties配置文件- 在主配置文件application.properties中指定要激活的环境
spring.profiles.active=dev
- 命令行
--spring.profiles.active=dev
配置命令行参数
项目打包后,也可以用java -jar xxx.jar --spring.profiles.active=dev
指定运行环境。 - 虚拟机参数
如果三种同时存在,命令行参数>虚拟机参数>properties/yml设置。
- 在主配置文件application.properties中指定要激活的环境
7. 配置文件加载位置
SpringBoot会扫描以下位置的application.properties或application.yml文件作为SpringBoot的默认配置文件。
高 file: ./config/ 即整个项目的根目录下的config目录
file: ./ 即整个项目的根目录下
classpath: /config/ 即resources/config目录下
低 classpath: / 即文件创建后生成的application.properties,resources目录下优先级最低
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容覆盖低优先级配置内容,如果4个位置都有application.properties,SpringBoot都会加载,同种配置高优先级覆盖低优先级,不同种配置不覆盖,形成互补配置。
打包成jar包后,可以用java -jar xxx.jar spring.config.location=硬盘下的application.properties文件路径
来用jar包外的配置文件覆盖jar包里的配置文件,互补配置,只覆盖同种配置,多个application.properties文件共同生效。
8. 外部配置加载顺序
9. 自动配置的原理
官方列举的配置文件能配置的属性:https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/appendix-application-properties.html#common-application-properties
- SpringBoot启动的时候加载主配置类,开启自动配置功能
@EnableAutoConfiguration
- @EnableAutoConfiguration的作用:利用AutoConfigurationImportSelector类给容器中导入一些组件?查看selectImports()方法,StringUtils.toStringArray(autoConfigurationEntry.getConfigurations())获取候选的配置,扫描所有jar包类路径下META-INF/spring.factories,把扫描到的这些文件的内容包装成一个properties对象,从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加到容器中。
SpringBoot2.3.0寻找路径:@EnableAutoConfiguration->AutoConfigurationImportSelector.class->selectImports方法->getAutoConfigurationEntry方法->getAutoConfigurationEntry方法->loadFactoryNames方法->loadSpringFactories的getResources("META-INF/spring.factories")
将类路径下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.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.r2dbc.R2dbcTransactionManagerAutoConfiguration,\ 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.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\ org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\ 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(Http编码自动配置)为例解释自动配置原理。
//HttpEncodingAutoConfiguration类上的注解
@Configuration( //表示这是一个配置类
proxyBeanMethods = false //不想通过调用方法来获取bean
)
@EnableConfigurationProperties({ServerProperties.class}) //启动指定类的ConfigurationProperties功能,将配置文件中对应的值和ServerProperties绑定起来,并把ServerProperties添加到容器中
@ConditionalOnWebApplication( //Spring底层@Conditional注解,根据不同的条件,只有满足指定条件,整个配置类里面的配置才会生效(判断当前应用是否是web应用,如果是,当前配置类生效)
type = Type.SERVLET //属性为servlet
)
@ConditionalOnClass({CharacterEncodingFilter.class}) //判断当前项目有没有这个类(CharacterEncodingFilter:SpringMVC中解决乱码的过滤器)
@ConditionalOnProperty( //判断配置文件中是否存在某个配置(server.servlet.encoding.enabled);如果不存在,判断也是成立的server.servlet.encoding.enabled=true,也是默认生效的
//即使配置文件中不配置
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();
}
@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@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类中封装着,配置文件能配置什么就可以参照某个功能对应的这个属性类。
@ConfigurationProperties( //从配置文件中获取指定的值和bean的属性进行绑定
prefix = "server",
ignoreUnknownFields = true //忽略未知字段
)
public class ServerProperties {...}
@Conditional派生注解
加了@Conditional派生注解的类,必须在@Conditional派生注解指定的条件成立,才会给容器添加组件,配置类里面的所有内容才生效。
自动配置类必须在一定的条件下才能生效。
开启SpringBoot的debug模式:在application.properties中加入debug=true
属性,可以在启动项目的时候,让控制台打印自动配置报告,可以很方便的知道哪些自动配置类生效。
Positive matches:启用的自动配置类
Negative matches:没启用和没匹配成功的自动配置类
下一篇笔记:SpringBoot入门篇学习笔记(二、日志与Web开发)
学习视频(p1-p20):https://www.bilibili.com/video/BV1gW411W76m?p=1