SpringBoot自动装配原理解析

转载至:  https://baijiahao.baidu.com/s?id=1630390576760652183&wfr=spider&for=pc

下载声明:  本资料仅供个人学习和研究使用,不能用于商业用途,请在下载后24小时内删除。如果喜欢,请购买正版!


自动装配是SpringBoot中一大特性,SpringBoot在程序初始化时可以根据classpath、property属性、context中实例、以及运行容器特征等各种动态条件,来按需初始化相应的bean,并注册到IOC容器中。


Spring Boot四大核心:

    1、自动配置:针对很多Spring应用程序和常见的应用功能,Spring Boot能自动提供相关配置。

    2、起步依赖:告诉Spring Boot需要什么功能, 它就能引入需要的依赖库

    3、Actuator:让你能够深入运行中的Spring Boot应用程序,一探Spring Boot程序的内部信息。

    4、命令行界面:这是Spring Boot的可选特性,主要针对Groovy语言使用。

本文将对自动装配的原理进行分析。

@EnableAutoConfiguration讲解

该注解表示开启Spring Boot自动配置功能,实现自动装配功能。

@EnableAutoConfiguration 定义:

在这个注解中,最重要的是它导入了一个类EnableAutoConfigurationImportSelector它是一个ImportSelector接口的实现类,而ImportSelector接口中的selectImports方法所返回的类将被Spring容器管理起来。

再看AutoConfigurationImportSelector类,它不光实现了ImportSelector接口,还实现了很多其它的Aware接口,分别表示在某个时机会被回调,我们看一下Aware接口就知道了。

我们可以知道,所有的aware都优先于selectImports方法执行,也就是说selectImports方法最后执行,那么在它执行的时候所有需要的资源都已经获取到了(就是那四个成员变量)。

那我们看看selectImports都干了什么:

看如下代码,获取类路径下spring.factories下key为EnableAutoConfiguration全限定名对应值:

List<String> configurations = getCandidateConfigurations(annotationMetadata,attributs);

getCandidateConfigurations会到classpath下的读取META-INF/spring.factories文件的配置,并返回一个字符串数组。

其结果为:

以上为Spring Boot中所有的自动配置相关类,在启动过程中会解析对应类配置信息。其加载机制是由spring框架的SpringFactoriesLoader组件实现的。

总结:

  1、加载META-INF/spring-autoconfigure-metadata.properties文件

  2、获取注解的属性及其值(PS:注解指的是@EnableAutoConfiguration注解)

  3、从classpath中搜索所有META-INF/spring.factories配置文件然后,将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration key对应的配置项加载到spring容器。只有spring.boot.enableautoconfiguration为true(默认为true)的时候,才启用自动配置,最终得到EnableAutoConfiguration的配置值,并将其封装到一个List中返回

  4、对上一步返回的List中的元素去重、排序。

  5、依据第2步中获取的属性值排除一些特定的类,排除方式有2中,一是根据class来排除(exclude),二是根据class name(excludeName)来排除。

  6、对上一步中所得到的List进行过滤,过滤的依据是条件匹配。这里用到的过滤器是org.springframework.boot.autoconfigure.condition.OnClassCondition最终返回的是一个ConditionOutcome[]数组。(PS:很多类都是依赖于其它的类的,当有某个类时才会装配,所以这次过滤的就是根据是否有某个class进而决定是否装配的。这些类所依赖的类都写在META-INF/spring-autoconfigure-metadata.properties文件里)。

  

关键点:


1、ImportSelector 该接口的方法的返回值都会被纳入到spring容器管理中

2、SpringFactoriesLoader 该类可以从classpath中搜索所有META-INF/spring.factories配置文件,并读取配置。



同理,其实Spring框架本身也提供了几个名字为@Enable开头的Annotation定义。比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和这些注解其实是一脉相承的。


观察@EnableAutoConfiguration可以发现,这里Import了@EnableAutoConfigurationImportSelector,这就是Spring Boot自动化配置的“始作俑者”。

至此,我们知道,由于我们在Spring Boot的启动类上使用了@SpringBootApplication注解,而该注解组合了@EnableAutoConfiguration注解,@EnableAutoConfiguration是自动化配置的“始作俑者”,而@EnableAutoConfiguration中Import了@EnableAutoConfigurationImportSelector注解,该注解的内部通过SpringFactoriesLoader.loadFactoryNames()读取了ClassPath下面的META-INF/spring.factories文件中key为的字符串数组,然后加载字节码,最后纳入到Spring IOC容器中。

Debug模式分析自动装配流程

先看看SpringBoot的主配置类:

里面有一个main方法运行了一个run()方法,在run方法中必须要传入一个被@SpringBootApplication注解的类。

@SpringBootApplication

SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就会运行这个类的main方法来启动SpringBoot项目。

那@SpringBootApplication注解到底是什么呢,点进去看看:

@SpringBootApplication

发现@SpringBootApplication是一个组合注解。

1、@SpringBootConfiguration

先看看@SpringBootConfiguration注解:

这个注解很简单,表名该类是一个Spring的配置类。

再进去看看@Configuration:

说明Spring的配置类也是Spring的一个组件。

2、@EnableAutoConfiguration

这个注解是开启自动配置的功能。

先看看该类上@AutoConfigurationPackage注解:

这个注解是自动配置包,主要是使用的@Import来给Spring容器中导入一个组件 ,这里导入的是Registrar.class。

来看下这个Registrar:

就是通过这个方法获取扫描的包路径,可以debug看看:

查看包名称

那那个metadata是什么呢:

可以看到是标注在@SpringBootApplication注解上的AutoconfigureSprongbootApplication,也就是我们的主配置类:

AnnotationMetadata类说白了就是将主配

现在包扫描路径获取到了,那具体加载哪些组件呢,看看下面这个注解。

@Import({AutoConfigurationImportSelector.class})

@Import注解就是给Spring容器中导入一些组件,这里传入了一个组件的选择器:AutoConfigurationImportSelector。

里面有一个selectImports方法,将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中。

selectImports方法

debug运行看看:

会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件:

自动装配导入的组件

有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。

那他是如何获取到这些配置类的呢,看看上面这个方法:

getCandidateConfigurations方法

会从META-INF/spring.factories中获取资源,然后通过Properties加载资源:

loadSpringFactories

Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作。以前我们需要自己配置的东西,自动配置类都帮我们完成了。

在spring-boot-autoconfigure-2.1.1.RELEASE.jar:

spring-boot-autoconfigure自动配置

比如看看CacheAutoConfiguration:都已经帮我们配置好了,我们不用再单独配置了:

CacheAutoConfiguration条件配置

整个Dubug分析完成,这就是SpringBoot自动装配流程,最核心的注解是@EnableAutoConfiguration,底层是通过使用了SpringFactoriesLoader服务发现机制和根据特定条件装备Bean的Conditionxxx条件注解实现的。


打赏 支付宝打赏 微信打赏

如果文章对您有帮助,欢迎移至上方打赏按钮...

随手一点
  • 打酱油

    6人

  • 28人

  • 呵呵

    3人

  • 草泥马

    1人

文章评论 (1)


  1. 沙发 来自 ssss 2020-06-23 18:58 回复 66666666666,看了这么多springboot,这篇写得很好,对我很有帮助,谢谢!!