头秃了,Spring Boot 自动配置源码解析了解一波~

  • 前言
  • 源码版本
  • @SpringBootApplication 干了什么?
  • @EnableAutoConfiguration 干了什么?
  • 总结

为什么 Spring Boot这么火?因为便捷,开箱即用,但是你思考过为什么会这么便捷吗?传统的SSM架构配置文件至少要写半天,而使用 Spring Boot之后只需要引入一个 starter之后就能直接使用,why???

原因很简单,每个 starter内部做了工作,比如 Mybatis的启动器默认内置了可用的 SqlSessionFactory

至于如何内置的? Spring Boot 又是如何使其生效的?这篇文章就从源码角度介绍一下 Spring Boot的自动配置原理。

源码版本

作者 Spring Boot是基于 2.4.0。每个版本有些变化,读者尽量和我保持一致,以防源码有些出入。

@SpringBootApplication干了什么?

这么说吧,这个注解什么也没做,废物,活都交给属下做了,源码如下:

(ElementType.TYPE)<br>(RetentionPolicy.RUNTIME)<br><br><br><br><br>(excludeFilters&#xA0;=&#xA0;{&#xA0;(type&#xA0;=&#xA0;FilterType.CUSTOM,&#xA0;classes&#xA0;=&#xA0;TypeExcludeFilter<span class="hljs-class">.<span class="hljs-keyword">class</span>),<br>&#xA0;&#xA0;@<span class="hljs-title">Filter</span>(<span class="hljs-title">type</span>&#xA0;</span>=&#xA0;FilterType.CUSTOM,&#xA0;classes&#xA0;=&#xA0;AutoConfigurationExcludeFilter<span class="hljs-class">.<span class="hljs-keyword">class</span>)&#xA0;})<br><span class="hljs-title">public</span>&#xA0;@<span class="hljs-title">interface</span>&#xA0;<span class="hljs-title">SpringBootApplication</span>&#xA0;</span>{}

上方标注了三个重要的注解,如下:

经过以上的分析,最终定位了一个注解 @EnableAutoConfiguration,顾名思义,肯定和自动配置有关,要重点分析下。

@EnableAutoConfiguration干了什么?

想要知道做了什么肯定需要看源码,如下:

(ElementType.TYPE)<br>(RetentionPolicy.RUNTIME)<br><br><br><br>(AutoConfigurationImportSelector<span class="hljs-class">.<span class="hljs-keyword">class</span>)<br><span class="hljs-title">public</span>&#xA0;@<span class="hljs-title">interface</span>&#xA0;<span class="hljs-title">EnableAutoConfiguration</span>&#xA0;</span>{}

上方标注了两个重要的注解,如下:

以上只是简单的分析了两个注解,下面将会从源码详细的介绍一下。

这个注解干了什么?这个需要看下源码,如下;

(ElementType.TYPE)<br>(RetentionPolicy.RUNTIME)<br><br><br>(AutoConfigurationPackages.Registrar<span class="hljs-class">.<span class="hljs-keyword">class</span>)<br><span class="hljs-title">public</span>&#xA0;@<span class="hljs-title">interface</span>&#xA0;<span class="hljs-title">AutoConfigurationPackage</span>&#xA0;</span>{}

重要的还是 @Import注解,导入了 AutoConfigurationPackages.Registrar,这个类是干什么的?源码如下图:

其实就两个方法,但是的最重要的就是 registerBeanDefinitions方法,但是这个方法不用看,肯定是注入 Bean,这里的重点是注入哪些 Bean,重点源码如下:

<br><span class="hljs-keyword">new</span>&#xA0;PackageImports(metadata).getPackageNames().toArray(<span class="hljs-keyword">new</span>&#xA0;String[<span class="hljs-number">0</span>])

跟进代码,主要逻辑都在 #PackageImports.PackageImports()这个构造方法中,源码解析如下图:

从上面源码分析可以知道,这里扫描的包名是由两部分组成,分别如下:

@AutoConfigurationPackage默认将主配置类(@SpringBootApplication)所在的包及其子包里面的所有组件扫描到IOC容器中。

这个注解不用多说了,最重要的就是 AutoConfigurationImportSelector,我们来看看它的继承关系,如下图:

这个类的继承关系还是挺简单的,实现了 Spring中的 xxAware注入一些必要的组件,但是最值得关心的是实现了一个 DeferredImportSelector这个接口,这个接口扩展了 ImportSelector,也改变了其运行的方式,这个在后面章节会介绍。

「 注意」:这个类会导致一个误区,平时看到 xxxSelector已经有了反射弧了,肯定会在 selectImports()方法上 DEBUG,但是这个类压根就没执行该方法,我第一次看也有点怀疑人生了,原来它走的是 DeferredImportSelector的接口方法。

其实该类真正实现逻辑的方法是 process()方法,但是主要加载自动配置类的任务交给了 getAutoConfigurationEntry()方法,具体的逻辑如下图:

上图的逻辑很简单,先从 spring.factories文件中获取自动配置类,在去掉 @SpringBootApplication中定义排除的自动配置类。

上图中的第 &#x2463;步就是从 META-INF/spring.factories中加载自动配置类,代码很简单,在上一篇分析启动流程的时候也有很多组件是从 spring.facotries文件中加载的,代码都类似。

springboot-autoconfigure中的 spring.facotries文件内置了很多自动配置类,如下:

#&#xA0;Auto&#xA0;Configure<br>org.springframework.boot.autoconfigure.EnableAutoConfiguration=\<br>org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\<br>org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\<br>org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\<br>org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\<br>org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\<br>org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\<br>org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\<br>org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\<br>org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\<br>org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\<br>................

了解了 Spring Boot 如何加载自动配置类,那么自定义一个自动配置类也是很简单了,后续章节教你如何定制自己的自动配置类,里面还是有很多门道的…..

本文从源码角度分析了 Spring Boot的自动配置是如何加载的,其实分析起来很简单,希望作者的这篇文章能帮助你更深层次的了解 Spring Boot

Original: https://www.cnblogs.com/Chenjiabing/p/14010257.html
Author: 爱撒谎的男孩
Title: 头秃了,Spring Boot 自动配置源码解析了解一波~

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/610777/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球