最近一直忙着在做新应届生的员工技术培训和面试 ,培训的则是Spring Boot部分的内容,这部分也是面试常问的点,于是想到了各位读者大大,特地的把内容分享大家一份。

不知道大家第一次搭Spring Boot环境的时候,有没有觉得非常简单。无须各种的配置文件,无须各种繁杂的pom坐标,一个main方法,就能run起来了。与其他框架整合也贼方便,使用EnableXXXXX注解就可以搞起来了!

所以咱们今天来讲讲Spring Boot是如何实现自动配置的~

首先咱们依旧来个总结:

Spring Boot自动配置流程图:

自动配置流程图

(▲如果图片看不清楚,可以添加名片回复:自动配置流程图,获取清晰版的全图)

看完流程图我们来一步步的分析(代码有点多干货同样也很多)

首先看源码的话我们就先从启动类开始入手:

@Spring BootApplication:Spring Boot应用标注在某个类上说明这个类是Spring Boot的主配置类,Spring Boot需要运行这个类的main方法来启动Spring Boot应用;

Spring BootApplication 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented@Inherited
@Spring BootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {      
@Filter(type = FilterType.CUSTOM, classes =TypeExcludeFilter.class),      
@Filter(type = FilterType.CUSTOM, classes =AutoConfigurationExcludeFilter.class) })
public @interface Spring BootApplication {

注解说明

注解 说明
@Target(ElementType.TYPE) 设置当前注解可以标记在哪
@Retention(RetentionPolicy.RUNTIME)

RetentionPolicy.RUNTIME会被jvm加载

RetentionPolicy.RUNTIME javadoc会生成注解信息
会被jvm加载
@Inherited 是否会被继承
@Spring BootConfiguration:Spring Boot的配置类; 标注在某个类上,表示这是一个Spring Boot的配置类;
@Configuration::配置类上来标注这个注解; 配置类-----配置文件;配置类也是容器中的一个组件;@Component
@EnableAutoConfiguration:开启自动配置功能; 以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉Spring Boot开启自动配置,会帮我们自动去加载自动配置类
@ComponentScan:扫描包 相当于在spring.xml配置中但是并没有指定basepackage,如果没有指定spring底层会自动扫描当前配置类所有在的包
TypeExcludeFilter Spring Boot对外提供的扩展类,可以供我们去按照我们的方式进行排除
AutoConfigurationExcludeFilter 排除所有配置类并且是自动配置类中里面的其中一个

精彩点来了

@EnableAutoConfiguration

在这个注解里面,最主要的就是@EnableAutoConfiguration,这么直白的名字,一看就知道它要开启自动配置,Spring Boot要开始天秀了,于是默默进去@EnableAutoConfiguration的源码。

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)
@Documented@Inherited@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public@interfaceEnableAutoConfiguration{
//略}

@AutoConfigurationPackage

将当前配置类所在包保存在BasePackages的Bean中。供Spring内部使用。

@AutoConfigurationPackage

@Import(AutoConfigurationPackages.Registrar.class)
//保存扫描路径,提供给spring-data-jpa需要扫描
@Entitypublic@interfaceAutoConfigurationPackage{

  1. 就是注册了一个保存当前配置类所在包的一个Bean

@Import(EnableAutoConfigurationImportSelector.class)关键点!

可以看到,在@EnableAutoConfiguration注解内使用到了@import注解来完成导入配置的功能,而EnableAutoConfigurationImportSelector实现了DeferredImportSelectorSpring内部在解析@Import注解时会调用getAutoConfigurationEntry方法,这块属于Spring的源码,有点复杂,我们先不管它是怎么调用的。下面是2.3.5.RELEASE实现源码:

getAutoConfigurationEntry方法进行扫描具有META-INF/spring.factories文件的jar包。

任何一个Spring Boot应用,都会引入spring-boot-autoconfigure,而spring.factories文件就在该包下面。spring.factories文件是Key=Value形式,多个Value时使用,隔开,该文件中定义了关于初始化,监听器等信息,而真正使自动配置生效的key是org.springframework.boot.autoconfigure.EnableAutoConfiguration,如下所示:

等同于

@Import({
#AutoConfigure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
...省略
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
})

每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

所有自动配置类表

  • 每一个自动配置类进行自动配置功能;

后续:@EnableAutoConfiguration注解通过@Spring BootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(...)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中

以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;

我们看看对应的注解阐述:

注解 说明
@Configuration(proxyBeanMethods=false) 标记了@ConfigurationSpring底层会给配置创建cglib动态代理。作用:就是防止每次调用本类的Bean方法而重新创建对象,Bean是默认单例的
@EnableConfigurationProperties(ServerProperties.class)

启用可以在配置类设置的属性对应的类

@xxxConditional根据当前不同的条件判断,决定这个配置类是否生效?

@Conditional派生注解(Spring注解版原生的@Conditional作用) 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@Conditional扩展注解作用 (判断是否满足当前指定条件)
@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项

我们怎么知道哪些自动配置类生效;

我们可以通过设置配置文件中:启用debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

下面我么就以HttpEncodingAutoConfiguration(Http编码自动配置)为例说明自动配置原理;

该注解如下:

  • @Configuration:表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件。
  • @ConditionalOnWebApplication:Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效;判断当前应用是否是web应用,如果是,当前配置类生效。

  • @ConditionalOnClass:判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器。

  • @ConditionalOnProperty:判断配置文件中是否存在某个配置spring.http.encoding.enabled;如果不存在,判断也是成立的

即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的。

  • @EnableConfigurationProperties({ServerProperties.class}):将配置文件中对应的值和ServerProperties绑定起来;并把ServerProperties加入到IOC容器中。并注册ConfigurationPropertiesBindingPostProcessor用于将@ConfigurationProperties的类和配置进行绑定

ServerProperties

ServerProperties通过@ConfigurationProperties注解将配置文件与自身属性绑定。

对于@ConfigurationProperties注解小伙伴们应该知道吧,我们如何获取全局配置文件的属性中用到,它的作用就是把全局配置文件中的值绑定到实体类JavaBean上面(将配置文件中的值与ServerProperites绑定起来),而@EnableConfigurationProperties主要是把以绑定值JavaBean加入到spring容器中。

到这里,小伙伴们应该明白,我们在application.properties声明spring.application.name是通过@ConfigurationProperties注解,绑定到对应的XxxxProperties配置实体类上,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。

所以只有知道了自动配置的原理及源码才能灵活的配置Spring Boot

粉丝福利

以上这几个就是今天给大家分享的内容,除此之外,我还为每位粉丝准备了一份全面的资料福利,从面试简历模板大厂面经汇总,从大厂内部技术资料互联网高薪必读书单,以及Java面试核心知识点(283页)Java面试题合集2022年最新版(485页)等等,有需要的可以点下方名片领取

Spring Boot 灵活实现自动配置背后的故事~用起来更香了相关推荐

  1. Spring Security 实战:Spring Boot 下的自动配置

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「码农小胖哥」 1. 前言 我们在前几篇 ...

  2. Spring Boot 面试杀手锏—自动配置原理

    点击关注公众号,回复"1024"获取2TB学习资源! 引言 不论在工作中,亦或是求职面试,Spring Boot已经成为我们必知必会的技能项.除了某些老旧的政府项目或金融项目持有观 ...

  3. Spring Boot面试杀手锏————自动配置原理

    引言 不论在工作中,亦或是求职面试,Spring Boot已经成为我们必知必会的技能项.除了某些老旧的政府项目或金融项目持有观望态度外,如今的各行各业都在飞速的拥抱这个已经不是很新的Spring启动框 ...

  4. spring boot (3.自动配置@enableautoconfiguration)

    主入口类/启动类 @SpringBootApplication 启动类是一个组合注解 配置类也是容器中的一个组件 第一个注解@springbootconfigration . @Target({Ele ...

  5. Spring Boot : Spring boot 的 AutoConfigurationImportSelector 自动配置原理

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

  6. datav本地部署 java,Spring Boot对Spring Data JPA的自动配置

    一 点睛 Spring Boot对Spring Data JPA的自动配置放置在如下路径: 二 源码分析 1 JpaRepositoriesAutoConfiguration类分析 @Configur ...

  7. spring boot rest接口自动生成文档(包含swagger)--gradle 下的配置

    之前写过一篇文章:spring boot rest接口自动生成文档(包含swagger),这个使用的是maven作为依赖管理工具,现在,让我们体验一下gradle在spring boot项目中如何配置 ...

  8. springboot 读取配置文件_使用 @ConfigurationProperties 在 Spring Boot 中加载配置

    本文地址: 使用 @ConfigurationProperties 在 Spring Boot 中加载配置 使用 Spring Boot 加载配置文件的配置非常便利,我们只需要使用一些注解配置一下就能 ...

  9. spring boot rest接口自动生成文档(包含swagger)

    spring boot rest接口自动生成文档(包含swagger)      写接口免不了写接口文档,但是当文档与代码分开独立演进的时候,会发生很多不同步的问题.         接口描述与代码同 ...

最新文章

  1. java项目中使用重定向返回字符串
  2. python中的集合类型_Python中的集合类型知识讲解
  3. Redis实现分布式锁原理SetNx命令
  4. [css]怎么改变选中文本的文字颜色和背景色?
  5. LeetCode 1496. 判断路径是否相交(set)
  6. 《C和指针》——在一组字符串中查找
  7. thymeleaf比较符号问题
  8. 静态成员常量的初始化
  9. 决定了 [2007-10-11]
  10. 从环境搭建探讨做事的方法
  11. STM32学习(1)-资料查找,STM32简介,STM32选型以及芯片内部结构图
  12. 印象笔记 离线版_印象笔记pc版离线
  13. 关于移动MM购买的相关资料
  14. itext使用字体问题
  15. 深入理解latch: cache buffers chains
  16. 微信和支付宝又更新了,这几个功能很赞
  17. H3C WX2510h无线控制器如何网关式部署无线网络
  18. FPGA异步信号寄存器打拍
  19. vue3.0引入百度地图并标记点
  20. vue 实时获取当前年月日时间星期

热门文章

  1. 优秀!初三毕业后,他直接去清华本硕博连读!
  2. 喷涂机器人主要组成部分
  3. 获取一个月份有多少天
  4. ai物流智能调度 效率对比_人工智能在物流中:人工智能改变物流的5种方式
  5. 关于C#中Delegate的使用
  6. timthumb.php下载,timthumb.php
  7. layout_weight的作用以及意义
  8. Android系统剪贴板(ClipboardManager)的使用: 通过代码复制和粘贴数据
  9. EXTJS 中grid 动态增加列的方法
  10. Bootstrap笔记(九) 排版 - 清單