SpringBoot自动装配原理

SpringBoot自动装配原理
要先了解SpringBoot自动装配原理我们就得了解@SpringBootApplication注解,他是由三个注解组合成的也就是@ComponentScan(扫描包)和@SpringBootConfiguration(本质就是@Configuration,扫描配置的注解)以及最重要的@EnableAutoConfiguration(自动装配注解)

@ComponentScan


 

其实也就是Spring的扫描注解,使得@SpringBootApplication实现了自动扫描父包和子包,这样使得我们的APP启动类要放在项目包下面,当然我们放在其他地方也可以,但是需要自己配置扫描路径,

我们以前需要配置包扫描器<context:component-scan base-package="com.test"/>.

@ComponentScan("com.test") 扫描包。
@SpringBootConfiguration


 

其实SpringBootConfiguration也就是@Configuration注解,他就是javaConfig形式的Spring Ioc容器的配置类使用的@Configuration,本身其实也是一个Ioc容器,以前是使用xml配置的,现在简化开发使用的Bean的来源。

@EnableAutoConfiguration


 

@EnableAutoConfiguration是一个复合注解,它其中最关键的注解便是@Import(EnableAutoConfigurationImportSelector.class)和@AutoConfigurationPackage

@AutoConfigurationPackage 里面其实是@Import(Registrar.class)里面存放的其实是包扫描器传过来的,也就是自动注册表。

@Import(EnableAutoConfigurationImportSelector.class)就比较重要了,它一路走下去就是加载了所有在META-INF下面的spring.factories中的自动装配对象,前提是我们导入了对应的启动类。也就是帮助了SpringBoot引用所有符合条件的@Configuration配置到当前SpringBoot所创建的Ioc容器中,就像一个八爪鱼一样借助于Spring原框架的一个工具类:SpringFactoriesLoader。这才使得@EnableAutoConfiguration自动装配的功能实现。



 

这个注解也是一个派生注解,主要的功能由@Import提供。@Import(AutoConfigurationImportSelector.class)

这是AutoConfigurationImportSelector的主要方法



 

它又调用了

AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
      autoConfigurationMetadata, annotationMetadata);


 

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


 

configurations里面有120个东西就是我们的META-INF/spring.factories里面的jar包我们继续往下走看它是怎么得到的。



 

这时候我们看到

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
      getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());


 

是不是很熟悉的方法loadFactoryNames这个方法扫描了了所有具有META-INF/spring.factories的jar包,

classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :


 

@EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)调用AutoConfigurationImportSelector中的selectImports调用getAutoConfigurationEntry中的getCandidateConfigurations的SpringFactoriesLoader.loadFactoryNames方法中的

Enumeration<URL> urls = (classLoader != null ?
      classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
      ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
      
      public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
FACTORIES_RESOURCE_LOCATION中存的就是所有带的jar包。

而在spring.factories文件也是一组一组的k-v的形式,k就是EnableAutoConfiguration的全类名,v是xxxxAutoConfiguration的类名的列表,用逗号隔开



 

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

自动配置生效
每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项

@ConditionalOnBean:当容器里有指定的bean的条件下。 @ConditionalOnMissingBean:当容器里不存在指定bean的条件下。 @ConditionalOnClass:当类路径下有指定类的条件下。 @ConditionalOnMissingClass:当类路径下不存在指定类的条件下。

在ServletWebServerFactoryAutoConfiguration类上,有一个@EnableConfigurationProperties注解:开启配置属性,而它后面的参数是一个ServerProperties类,这就是习惯优于配置的最终落地点。



在这个类上有个ConfigurationProperties注解,他的作用就是从配置文件中绑定属性到对应的bean上,而@EnableConfigurationProperties负责导入已经绑定了属性的bean到Spring容器中,那么所有和他相关的属性都可以在全局配置文件中定义,限制全局配置文件中配置那些属性就是XxxxProperties类,他与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。

全局配置文件中的属性通过@ConfigurationProperties注解绑定到对应的Properties配置实体类上封装为一个bean,再通过@EnableConfigurationProperties注解导入到Spring容器中。

而诸多的XxxxAutoConfiguration自动配置类,就是Spring容器的JavaConfig形式,作用就是为Spring 容器导入bean,而所有导入的bean所需要的属性都通过xxxxProperties的bean来获得。

面试解答

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。
当然不是所有的jar包我们都用的上,当我们导入了对应的启动器他才能供我们使用详情看这里



 

这些是条件注解,只有导入了启动类,条件注解检测到了有对应的类,这个类才会自动化配置。

最后奉上大图

 
————————————————
版权声明:本文为CSDN博主「本来写bug却写成了程序」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_57560984/article/details/120178077
#Java开发##Spring##学习路径#
全部评论
借楼发个招聘,富途,港美股互联网券商, 内推链接:富途校园招聘 (futunn.com),内推码:NTAFTD0 内推链接如下 手机版复制到微信打开(网页版可以直接打开) app.mokahr.com/recommendation-apply/futu5/1699?sharePageId=821019&recommendCode=NTAFTD0&codeType=1#/recommendation/page/821019
点赞 回复
分享
发布于 2021-10-01 17:15

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午&nbsp;腾讯csig&nbsp;腾讯云部门,面完秒进入复试状态4.16下午&nbsp;美团优选供应链部门,4.18上午发二面4.17晚上&nbsp;阿里国际一面,纯拷打,面完我都玉玉了4.18下午&nbsp;阿里国际二面,是我们leader面的我,很轻松~~4.18晚上&nbsp;约了hr面4.19上午&nbsp;hr面,下午两点口头oc4.19晚上&nbsp;意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月&nbsp;&nbsp;一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月&nbsp;莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
转发
5 24 评论
分享
牛客网
牛客企业服务