主程序类的注解 @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,\

代码解析:

  1. 在 application.properties 文件中配置的时候指定前缀是 spring.http;
  2. 指定默认的编码方式是 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() {
......
}
.......
}

源码解析:

  1. 表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件。
  2. 启动指定类的 ConfigurationProperties 功能,将配置文件中对应的值和 HttpEncodingProperties 绑定起来;并把 HttpEncodingProperties 加入到 IOC 容器中;
  3. Spring 底层 @Conditional 注解(有关 @Conditional 注解的详解请参考后续 Spring 注解相关文章),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效,该注解是判断当前应用是否是web应用,如果是, HttpEncodingAutoConfiguration 配置类生效;
  4. 判断当前项目有没有这个类 CharacterEncodingFilter;SpringMVC 中进行乱码解决的过滤器,如果有则 HttpEncodingAutoConfiguration 配置生效;
  5. 判断 application.properties 配置文件中是否存在 spring.http.encoding.enabled,如果不存在,判断也是成立的,因为 matchIfMissing=true,即缺省时默认为 true。

根据当前不同的条件判断,决定 HttpEncodingAutoConfiguration 这个配置类是否生效?一但这个配置类生效;这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的 HttpEncodingProperties 类中获取的,这些类里面的每一个属性又是和配置文件绑定的。

2.3 @Conditional扩展注解

除了以上解析到的注解,SpringBoot 还为我们提供了更多的有关 @Conditional 的派生注解。它们的作用:必须是 @Conditional 指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效:

原文出处: 晴枫

SpringBoot系列二:SpringBoot自动配置原理的更多相关文章

  1. SpringBoot:配置文件及自动配置原理

    西部开源-秦疆老师:基于SpringBoot 2.1.6 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! SpringBoot ...

  2. springboot(3)——配置文件和自动配置原理详细讲解

    原文地址 目录 概述 1. 配置文件作用 2.配置文件位置 3.配置文件的定义 3.1如果是定义普通变量(数字 字符串 布尔) 3.2如果是定义对象.Map 3.3如果是定义数组 4.配置文件的使用 ...

  3. SpringBoot嵌入式Tomcat的自动配置原理

    在读本篇文章之前如果你读过这篇文章SpringBoot自动装配原理解析应该会更加轻松 准备工作 我们知道SpringBoot的自动装配的秘密在org.springframework.boot.auto ...

  4. SpringBoot源码学习系列之SpringMVC自动配置

    目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...

  5. SpringBoot自动化配置之二:自动配置(AutoConfigure)原理、EnableAutoConfiguration、condition

    自动配置绝对算得上是Spring Boot的最大亮点,完美的展示了CoC约定优于配置: Spring Boot能自动配置Spring各种子项目(Spring MVC, Spring Security, ...

  6. springboot核心技术(二)-----自动配置原理、日志

    自动配置原理 配置文件能配置的属性参照 1.自动配置原理: 1).SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration 2).@Enable ...

  7. SpringBoot源码学习系列之异常处理自动配置

    SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...

  8. SpringBoot入门一:基础知识(环境搭建、注解说明、创建对象方法、注入方式、集成jsp/Thymeleaf、logback日志、全局热部署、文件上传/下载、拦截器、自动配置原理等)

    SpringBoot设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,SpringBoot致力于在蓬勃发 ...

  9. SpringBoot自动配置原理

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习的顺序排好): S ...

  10. SpringBoot的自动配置原理过程解析

    SpringBoot的最大好处就是实现了大部分的自动配置,使得开发者可以更多的关注于业务开发,避免繁琐的业务开发,但是SpringBoot如此好用的 自动注解过程着实让人忍不住的去了解一番,因为本文的 ...

随机推荐

  1. layui 的学习

    1. meta标签 https://www.cnblogs.com/wangyang108/p/5995379.html <meta name="viewport" cont ...

  2. Java多线程-线程池ThreadPoolExecutor构造方法和规则

    为什么用线程池 原文地址 http://blog.csdn.net/qq_25806863/article/details/71126867 有时候,系统需要处理非常多的执行时间很短的请求,如果每一个 ...

  3. Shell命令-文件压缩解压缩之gzip、zip

    文件及内容处理 - gzip.zip 1.gzip:gzip压缩工具 gzip命令的功能说明 gzip 命令用于压缩文件.gzip 是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多出 .gz ...

  4. [模板] 笛卡尔树 && RMQ

    话说我noip之前为什么要学这种东西... 简介 笛卡尔树(Cartesian Tree) 是一种二叉树, 且同时具有以下两种性质: 父亲节点的值大于/小于子节点的值; 中序遍历的结果为原序列. 笛卡 ...

  5. Ninja编译过程分析

    在Android N的系统上,初次使用了Ninja的编译系统.对于Ninja,最初的印象是用在了Chromium open source code的编译中,在chromium的编译环境中,使用ninj ...

  6. zabbix误报交换机重启

    交换机的sysUpTime是由一个32-bit的counter来计数的,单位是0.01秒,所以最大时间为496天,过了496天就溢出,变成0,然后又重新计算时间,所以zabbix误报. snmpwal ...

  7. 阶梯Nim问题

    问题形式 有\(n\)个位置\(1...n\),每个位置上有\(a_i\)个石子.有两个人轮流操作.操作步骤是:挑选\(1...n\)中任一一个存在石子的位置\(i\),将至少1个石子移动至\(i-1 ...

  8. Springboot 2.返回cookies信息的get接口开发 和 带cookis去请求

    首先要有一个启动类,默认的启动类的名字就是Application.java.启动的时候直接右键点击run就可以 Application.java: import org.springframework ...

  9. ASP.NET概念

    ASP.NET :是一个开发框架,用于通过 HTML.CSS.JavaScript 以及服务器脚本来构建网页和网站. ASP.NET两种开发语言:VB C#

  10. javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/websocket/{sid}] : existing endpoint was class com.sanyi.qibaobusiness.framework.webSocket.WebSocketServe

    报错: javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/w ...