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

相关推荐

华为慧通是华为全资子公司,签的是华为慧通,不是华为od(外包),类似于小米和小米之家和以前华为和荣耀的关系。💼&nbsp;公司岗位杭州终端销售代表(非销售),感觉类似于产品经理&nbsp;&nbsp;由于我们学校有来直接线下校招,所以投简历完直接进面试了,不用去官网投递。&nbsp;&nbsp;面试是集体面试,不到十个人左右,有本科生有研究生。大概讲一下流程:&nbsp;①首先是每个人三分钟自我介绍,介绍姓名学校专业以及个人的一些主要经历,三分钟左右讲完还是绰绰有余的。&nbsp;②面试官开始出题,第一题大概就是产品出了问题,如何解决客户问题。该问题可以拓展出很多内容,比如店员培训提高积极性,产品营运,后期产品管理流程优化防止类似情况再发生等等。&nbsp;③开始个人面试流程,通过对简历进行问答,因为我个人是计算机专业,所以项目上一水的技术经历,所以面试官问的就是“你的项目以技术为主为什么来我们岗位”“你在这些项目中承担了什么工作”“如果你的队员在项目中无法按时解决任务你要怎么解决”等一面就是这样,感觉非常像产品经理,听说终端销售代表还有自己的方向比如政企,渠道,零售等等,薪资待遇一般,远低于正编和od,毕竟岗位技术性较低。----------分割线做完性格测试就挂了,夸张。
点赞 评论 收藏
转发
5 24 评论
分享
牛客网
牛客企业服务