SpringBoot 的精髓就是可以自动配置,减少了开发人员编写配置文件的工作量,提高开发效率。
<br/>
SpringBoot提供了哪些自动配置参考[官方文档](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#appendix)。
<br/>
SpringBoot能够实现自动配置,是因为它通过一个过程最终找到了文件`META-INF/spring.factories`,并读取该文件提供的配置插件来完成自动配置,在创建 SpringBoot 项目后,你可以如下图查看提供了哪些自动配置。
![](https://img.kancloud.cn/dc/fb/dcfbeea3f1f031abcc29a82970be7542_1857x429.jpg)
<br/>
它的自动配置原理如下,通过启动类上的`@SpringBootApplication`入口找到下面的过程:
```
当SpringBoot启动后,它通过下面的过程来加载自动配置
@SpringBootApplication
->
@EnableAutoConfiguration
->
@Import({AutoConfigurationImportSelector.class})
->
AutoConfigurationImportSelector.selectImports(...) -> getAutoConfigurationEntry(...)
-> List<String> configurations = getCandidateConfigurations(...)
->getCandidateConfigurations(...)->SpringFactoriesLoader.loadFactoryNames(...)
->
SpringFactoriesLoader.loadSpringFactories(...)-> classLoader.getResources("META-INF/spring.factories")
->
AutoConfigurationImportSelector.getCandidateConfigurations(...)->
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(),
->
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
最终方法返回EnableAutoConfiguration.class,将该类的所有组件加入到容器中
->
META-INF/spring.factories
->
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
```
找到`META-INF/spring.factories`文件中的自动配置组件,将这些组件加入到容器中,使得这些组件起作用。
<br/>
下面我们选取HttpEncodingAutoConfiguration这个自动配置组件来研究下,它的部分源码如下:
```java
// 配置类,与application.properties,或application.yml配置文件是同等效果
@Configuration(
proxyBeanMethods = false
)
// 将ServerProperties类中的相关配置加载到当前配置中
// 点击ServerProperties.class进去后,你会看到很多待配置的属性
// ServerProperties中属性与配置文件中的属性对应起来,并获取配置文件中相应属性的值
@EnableConfigurationProperties({ServerProperties.class})
// 底层是Spring的@Conditional注解,根据当前的应用程序是不是Web应用,
// 是则让HttpEncodingAutoConfiguration这个配置类生效,否则不让生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
// 判断当前项目中是否有CharacterEncodingFilter这个类,有则让这个类生效
// CharacterEncodingFilter是我们在学习SpringMVC时用来处理中文乱码的过滤器
@ConditionalOnClass({CharacterEncodingFilter.class})
// 判断配置文件中是否存在server.servlet.encoding配置,它的默认值为enabled
// 而matchIfMissing为true表示不论是否存在server.servlet.encoding配置
// 都让HttpEncodingAutoConfiguration这个配置类生效
@ConditionalOnProperty(
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)
// 这个自动用一句话概括就是:根据条件来决定是否让这个配置生效
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
// 通过自身的构造器获取ServerProperties,然后提供给自身
public HttpEncodingAutoConfiguration(ServerProperties properties) {
this.properties = properties.getServlet().getEncoding();
}
// 当上面的@ConditionalOnWebApplication、@ConditionalOnClass
//、@ConditionalOnProperty三个条件都成立后。@Bean就会往容器中添加
// CharacterEncodingFilter组件,这个组件属性的值从ServerProperties中获取
@ConditionalOnMissingBean // 如果CharacterEncodingFilter还没有被注入容器中,则将其注入并让这个组件生效
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;
}
```
ServerProperties的部分源码如下,我们可以看到有许多的配置属性:
```java
@ConfigurationProperties(
prefix = "server",
ignoreUnknownFields = true
)
public class ServerProperties {
private Integer port;
private InetAddress address;
@NestedConfigurationProperty
private final ErrorProperties error = new ErrorProperties();
private ServerProperties.ForwardHeadersStrategy forwardHeadersStrategy;
private String serverHeader;
private DataSize maxHttpHeaderSize = DataSize.ofKilobytes(8L);
private Shutdown shutdown;
```
总结如下:
在每个XXXAutoConfiguration类中,都会通过@EnableConfigurationProperties将相应的XXXProperties类加载到当前的XXXAutoConfiguration类中,而XXXProperties类上相应的属性已与`application.properties`,或`application.yml`配置文件绑定,可以获取配置文件中的属性值。XXXAutoConfiguration使用@Bean和 @ConditionalOnMissingBean将它加入到容器中,所以最终可以读取到配置文件中配置信息并使自身起作用。
<br/>
SpringBoot的精髓就是可以自动配置,减少了开发人员编写大量配置文件的工作量,提高开发效率。所以我们应该如下应用SpringBoot的自动配置:
1. SpringBoot启动会加载大量的自动配置类;
2. 我们看我们需要的功能SpringBoot有没有已经帮我们默认自动配置了;
3. 我们再来看这个自动配置类中到底配置了哪些组件,如果没有我们要的配置组件,则再由我们自定义;
4. 给容器中的自动配置类添加组件的时候,会从XXXProperties类中获取某些属性,这些属性我们就可以在`application.properties`或`application.yml`中进行指定;
5. 通过封装XXXProperties类与配置文件进行绑定,然后加载到XXXAutoconfig类中让这些属性起作用。
- Mybatis
- mybatis是什么
- mybatis优缺点
- 环境搭建
- 使用步骤
- 传参方式
- 无需传参
- 一个参数
- 多个参数
- 增/删/改
- 查询
- 单表查询
- 一对一查询
- 一对多查询
- 动态SQL
- 注解操作
- Spring
- Spring什么
- Spring优点
- Spring组成
- 第一个Spring程序
- 两大核心技术
- IoC控制反转
- IoC思想
- IoC容器使用步骤
- 属性注入
- IoC注入方式
- 模拟IoC实现
- AOP
- AOP概念
- AOP原理
- AOP关键术语
- AOP编程过程
- 切入点规则
- 5种增强方式
- Spring注解开发
- 注解开发的优势
- Bean注解开发
- AOP注解开发
- 完全注解开发
- 模拟Spring注解开发
- 自动装配
- 配置文件拆分
- SpringBean
- Bean常用属性
- Bean的作用域
- Bean的生命周期
- Spring整合MyBatis
- 整合步骤
- SqlSessionTemplate
- 业务层添加事务
- 事务的作用
- 配置文件事务
- 注解事务
- 事务参数
- SpringMVC
- SpringMVC是什么
- 环境搭建
- 请求流程
- 核心组件
- 前后端交互
- 简单交互演示
- 常用注解
- 后端数据传递至前端
- ServletAPI
- 访问静态资源
- 异常处理
- HandlerExceptionResolver
- 局部异常
- 全局异常
- 转发与重定向
- 转发演示
- 重定向演示
- 转发与重定向的区别
- 获取表单数据
- 表单标签
- REST风格的URL
- 异步处理
- 异步请求
- JSON数据处理
- 中文乱码处理
- 日期处理
- 上传文件
- 拦截器
- 视图解析器
- 视图类型
- 多视图解析器
- 自定义pdf视图
- JSR303数据验证
- JSR303是什么
- 常用约束
- 使用步骤
- SpringMVC整合Mybatis
- 整合步骤
- Mybatis分页插件
- SpringBoot
- SpringBoot是什么
- 环境搭建
- SpringBoot启动分析
- SpringBoot启动类
- 启动过程
- SpringBoot配置文件
- 配置文件类型
- 更改配置文件
- 读取配置文件
- 占位符
- 配置优先级
- 自定义IoC容器
- 定义方式
- 引入Spring配置文件
- @Configuration
- SpringBoot自动配置
- 自动配置原理
- 条件注解
- 自动配置报告
- 自定义自动配置
- 关闭自动配置
- 接管自动配置
- 多环境配置
- CommandLineRunner
- SpringBoot与Web开发
- 引入模板引擎
- Thymeleaf模板
- Freemarker模板
- 静态资源访问
- webjars
- 静态资源位置
- ico图标
- 指定首页
- 更换Web服务器
- 国际化
- 拦截器
- 错误处理机制
- 错误处理机制原理
- 定制错误页面
- 定制错误数据
- 上传文件
- 注册servlet三大组件
- 注册Servlet
- 注册过滤器
- 注册监听器
- 外部Tomcat与jsp模板
- 前后端交互
- 传递json字符串
- 传递js对象
- 传递表单
- 下载功能
- Swagger2文档
- SpringBoot整合JDBC
- 整合步骤
- 核心API
- JdbcTemplate
- 增删改
- 查询
- NamedParameterJdbcTemplate
- 增删改
- 查询
- SpringBoot整合Mybatis
- 整合步骤
- 切换为Druid数据源
- 添加事务
- Mybatis分页插件
- 场景启动器
- 场景启动器是什么
- 自定义场景启动器
- SpringBoot与日志
- 日志框架
- slf4j日志
- slf4j日志实现
- 统一切换为slf4j
- 日志配置
- 日志文件
- 切换日志框架
- 切换日志场景启动器
- SpringBoot与缓存
- JSR107缓存技术
- Spring缓存抽象
- 缓存注解
- SpEL表达式
- 使用缓存
- 自定义key生成器
- 缓存工作原理与流程
- SpringBoot整合Redis
- 整合步骤
- 初步使用
- 序列化机制
- 缓存管理器
- SpringBoot与任务
- 异步任务
- 实现异步任务
- 注意事项与原理
- 自定义线程池
- 定时任务
- cron表达式
- 创建定时任务
- @Scheduled参数
- 动态时间
- 邮件任务
- Quartz定时任务
- Quartz是什么
- 创建定时任务
- 触发器与任务
- 任务的CURD
- 两种触发器
- 并发问题
- 持久化
- 任务持久化
- Quartz集群
- misfire策略
- 打包插件
- appassembler-maven-plugin
- appassembler与assembly配合