SpringBoot系列二:SpringBoot自动配置原理
主程序类的注解 @SpringBootApplication 注解,它其实是个组合注解,源码如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
),
@Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}
最主要的还是三个配置 @SpringBootConfiguration、@EnableAutoConfigration、@ComponentScan 三个注解,下面我们来一一分析。
1.1 @SpringBootConfiguration
查看@SpringBootConfiguration源码,其实它也就是@Configuration注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
对于 @Configuration,我们并不陌生,它就是 JavaConfig 形式的 SpringIOC 容器的配置类,也是 SpringBoot 推荐使用配置形式,所以主程序类标注了 @SpringBootConfiguration 注解,其本身也就是一个配置类。更多有关 JavaConfig 形式的配置以及有关它和 XML 形式的配置的区别与联系,请参考后续有关 Spring 注解版相关文章。
1.2 @ComponentScan
@ComponentScan 注解在 Spring 的注解中也起到到相当重要的作用,它可以自定义 Spring 扫描的包,也就是它默认会扫描标注了 @Controller、@Service、@Component 以及 @Repository 注解的类,并实例化这些组件到 SpringIOC 容器中,它有个配置属性: basePackages,也就是指定扫描的包,如果不知道,它会默认扫描配置了该注解的类的包所在的路径(包括子包)。我们看 @SpringBootConfiguration 注解的源码中有段代码:
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
scanBasePackages 属性,指定到了 @ComponentScan 注解的 basePackages 属性,所有在 SpringBoot 中,我们同样可以通过 scanBasePackages 属性指定包扫描的路径(如部指定,会默认扫描主程序类所在的包路径以及子包下的类):
@SpringBootApplication(scanBasePackages = "com.seagetech.springbootdemo")
1.3 @EnableAutoConfigration
关于 SpringBoot 的运作原理,它的核心功能还是由 @EnableAutoConfigration 注解提供,所有把它放到最后来讲,我们来看下它的源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
1.3.1 @AutoConfigurationPackage
这个注解的主要功能自动配置包,它会获取主程序类所在的包路径,并将包路径(包括子包)下的所有组件注册到 SpringIOC 容器中。
1.3.2 @Import({AutoConfigurationImportSelector.class})
@EnableAutoConfiguration 的关键功能也是这个 @Import 导入的配置功能,使用 SpringFactoriesLoader.loadFactoryNames 方法来扫描具有 META-INF/spring.factories 文件的jar包,我们看看在 spring-boot-autoconfigure-2.10.RELEASE.jar 包的 META-INF 下正好有个 spring.factories 文件:

打开 spring.factories 文件,找到 org.springframework.boot.autoconfigure.EnableAutoConfiguration 指定的自动配置类:
# 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.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,\
代码解析:
- 在 application.properties 文件中配置的时候指定前缀是 spring.http;
- 指定默认的编码方式是 UTF-8,如果需要修改,可使用 spring.http.encoding.charset=编码。
2.2 自动配置类
@Configuration//①
@EnableConfigurationProperties({HttpProperties.class})//②
@ConditionalOnWebApplication(
type = Type.SERVLET
)//③
@ConditionalOnClass({CharacterEncodingFilter.class})//④
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)//⑤
public class HttpEncodingAutoConfiguration {
private final Encoding properties; public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
} @Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
......
}
.......
}
源码解析:
- 表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件。
- 启动指定类的 ConfigurationProperties 功能,将配置文件中对应的值和 HttpEncodingProperties 绑定起来;并把 HttpEncodingProperties 加入到 IOC 容器中;
- Spring 底层 @Conditional 注解(有关 @Conditional 注解的详解请参考后续 Spring 注解相关文章),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效,该注解是判断当前应用是否是web应用,如果是, HttpEncodingAutoConfiguration 配置类生效;
- 判断当前项目有没有这个类 CharacterEncodingFilter;SpringMVC 中进行乱码解决的过滤器,如果有则 HttpEncodingAutoConfiguration 配置生效;
- 判断 application.properties 配置文件中是否存在 spring.http.encoding.enabled,如果不存在,判断也是成立的,因为 matchIfMissing=true,即缺省时默认为 true。
根据当前不同的条件判断,决定 HttpEncodingAutoConfiguration 这个配置类是否生效?一但这个配置类生效;这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的 HttpEncodingProperties 类中获取的,这些类里面的每一个属性又是和配置文件绑定的。
2.3 @Conditional扩展注解
除了以上解析到的注解,SpringBoot 还为我们提供了更多的有关 @Conditional 的派生注解。它们的作用:必须是 @Conditional 指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效:

原文出处: 晴枫
SpringBoot系列二:SpringBoot自动配置原理的更多相关文章
- SpringBoot:配置文件及自动配置原理
西部开源-秦疆老师:基于SpringBoot 2.1.6 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! SpringBoot ...
- springboot(3)——配置文件和自动配置原理详细讲解
原文地址 目录 概述 1. 配置文件作用 2.配置文件位置 3.配置文件的定义 3.1如果是定义普通变量(数字 字符串 布尔) 3.2如果是定义对象.Map 3.3如果是定义数组 4.配置文件的使用 ...
- SpringBoot嵌入式Tomcat的自动配置原理
在读本篇文章之前如果你读过这篇文章SpringBoot自动装配原理解析应该会更加轻松 准备工作 我们知道SpringBoot的自动装配的秘密在org.springframework.boot.auto ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- SpringBoot自动化配置之二:自动配置(AutoConfigure)原理、EnableAutoConfiguration、condition
自动配置绝对算得上是Spring Boot的最大亮点,完美的展示了CoC约定优于配置: Spring Boot能自动配置Spring各种子项目(Spring MVC, Spring Security, ...
- springboot核心技术(二)-----自动配置原理、日志
自动配置原理 配置文件能配置的属性参照 1.自动配置原理: 1).SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration 2).@Enable ...
- SpringBoot源码学习系列之异常处理自动配置
SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...
- SpringBoot入门一:基础知识(环境搭建、注解说明、创建对象方法、注入方式、集成jsp/Thymeleaf、logback日志、全局热部署、文件上传/下载、拦截器、自动配置原理等)
SpringBoot设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,SpringBoot致力于在蓬勃发 ...
- SpringBoot自动配置原理
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习的顺序排好): S ...
- SpringBoot的自动配置原理过程解析
SpringBoot的最大好处就是实现了大部分的自动配置,使得开发者可以更多的关注于业务开发,避免繁琐的业务开发,但是SpringBoot如此好用的 自动注解过程着实让人忍不住的去了解一番,因为本文的 ...
随机推荐
- 7 Servlet 会话技术
1 什么是会话 用户开一个浏览器访问某个网站,点击多个链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为会话,与打电话类似.会话过程要解决一些问题, 每个用户在使用浏览器与服务器进行会话时 ...
- 使用ffmpeg视频切片并加密
想达到的目的:将一个mp4视频文件切割为多个ts片段,并在切割过程中对每一个片段使用 AES-128 加密,最后生成一个m3u8的视频索引文件: 电脑环境 Fedora,已经安装了最新的ffmpeg: ...
- servlet篇 之 跳转问题
servlet中的跳转: 跳转本质上是对文件传输操作 进行 封装. 例如:客户端访问一个servlet,在servlet中需要把已经写好的页面hello.html返回给客户端浏览器,需要用io来实现这 ...
- 存储引擎和表的操作(mysql中的数据类型、完整性约束)
一.存储引擎 .概念 MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力. 通过选择不同的技术 ...
- BZOJ1975[Sdoi2010]魔法猪学院——可持久化可并堆+最短路树
题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...
- 自用windows小软件
好用的软件的定义:没有广告,提升效率,最低的内存占用,体积小 1.解压工具 bandizip:自动解压功能,棒呆了 网址:https://www.bandisoft.com/ 2.pdf阅读编辑工具 ...
- [ML]机器学习书单
https://anvaka.github.io/greview/hands-on-ml/1/
- es上的的Watcher示例
Watcher插件配置(创建预警任务) watcher目前是沒有界面配置的,需要通过Resfulapi调用创建.管理.更新预警任务 创建一个Watcher任务的流程是怎样的? 我们先来看下创建一个预警 ...
- 关于Oracle.ManagedDataAccess数据库表加字段后,必须重启的问题
关于Oracle.ManagedDataAccess数据库表加字段后,必须重启的问题,解决方法如下:在数据库连接字串中,增加一个参数:Metadata Pooling=false如“Data Sour ...
- visual studio 不能跳转到函数定义
解决办法: 工具-->扩展和更新-->联机.搜索“Go To Definition”下载然后关闭visualstudio进行安装,重启后就ok了