SpringBoot自动配置(源码解读)

背景

我参加SpringBoot项目开发也已经五个多月时间了,项目遇到一个大数据量文本的取存问题,DBA不允许我们存text或者blob类型的数据在MySQL中,不得已采取了ElasticSearch作为一个中间数据库使用,然后根据网上的方法把maven依赖导入,application.properties粘贴过来,发现已经引入了ElasticSearch这个组件,最后把问题解决了。

但是这也引发了我的思考,为啥SpringBoot可以自动识别并且帮我初始化ES呢?阅读了SpringBoot源码,我按照我的理解讲一下SpringBoot的自动配置。

理论知识

创建一个SpringBoot项目,它会帮我们生成我们开发者所需要的环境,它的一个注解@SpringBootApplication可以帮助我们开发者开启自动配置并且初始化我们所需要的bean。
在这里插入图片描述

但是@SpringBootApplication为什么可以这样呢?

点进去看这个注解,原来这个注解是一个复合注解,里面还有一个@EnableAutoConfiguration,顾名思义就是自动开启配置。

在这里插入图片描述

然后再点进去查看它的源码
在这里插入图片描述

发现原来SpringBoot自动配置的关键就是这个注解@Import({AutoConfigurationImportSelector.class}),点进去查看源码
在这里插入图片描述

它的作用就是导入AutoConfigurationImportSelector的selectImports方法,通过SpringFactoriesLoader.loadFactoryNames()扫描所有META-INF/spring.factories的jar包。然后spring-boot-autoconfigure-2.4.1.jar里面有一个spring.factories文件。该文件由一堆key=value组成,其中key是EnableAutoConfiguration类的全类名,而value是xxxAutoConfiguration的类名列表,以逗号分隔。
在这里插入图片描述
在这里插入图片描述

上面所列出来的org.springframework.boot.autoconfigure.xxx.yyyAutoConfiguration列表会被初始化到Spring容器中。

当SpringBoot项目启动时,@SpringBootApplication在启动类SpringApplication.run(xxx.class)的内部会执行selectImports()方法,找到所有自动配置类的全限定名对应的class,然后把所有的自动配置类加载到Spring容器中。

那么这么多xxxAutoConfiguration类都会被加载吗?

答案是不会。因为注解类会有一个@ConditionalOnClass注解,只要在当前的类路径下找到对应的类才会被加载,否则放弃加载并且初始化到Spring容器中。

这就很好理解为啥SpringBoot项目引入一个依赖就能自动帮你初始化bean了吧。

举例说明

举例我最近用的elasticSearch的配置信息如何加载到bean容器中的。

引入组件所需要的maven依赖:
在这里插入图片描述

配置application.properties基础信息:

在这里插入图片描述

为何要这样配置呢?源码告诉你答案。

springboot自动配置全都是由autoconfigure注入的,打开maven引入的autoconfigure的jar包
在这里插入图片描述

SpringBoot加载会读取里面的spring.factories文件

在这里插入图片描述

所有的配置都是由org.springframework.boot.autoconfigure.EnableAutoConfiguration来完成注入,格式都是为org.springframework.boot.autoconfigure.xxx.yyyAutoConfiguration。

拿我们配置的elasticsearch来说明一下,点进去看它配置的源码

在这里插入图片描述
在这里插入图片描述

可以看到有一个注解@EnableConfigurationProperties,就是用来配置和初始化bean的。点进去看ElasticsearchRestClientProperties的配置信息
在这里插入图片描述

一切恍然大悟,原来这里的@ConfigurationProperties(prefix=“spring.elasticsearch.rest”)已经规定了配置文件该如何写了,就是限制了前缀"spring.elasticsearch.rest",后面的uris的类型是List代表它支持集群,可以加载多个服务器。然后它们有对应的get/set方法可以帮助我们开发者注入,这就对应上我们的application.properties文件了吧。
在这里插入图片描述

就是通过这种方式注入到bean容器并且初始化的,这就是springboot的“约定大于配置”。

类比其他配置信息

我直接把springboot中redis的约定贴出来,你们也可以对比一下你们自己的项目配置,知道为什么要这样写就行了。
在这里插入图片描述
在这里插入图片描述

总结

通过这一次项目引入ElasticSearch引发的一场SpringBoot自动配置源码阅读,我觉得还是受益匪浅的,希望以上的内容对正在学SpringBoot或者已经工作的开发者们有帮助。

猜你喜欢

转载自blog.csdn.net/weixin_37686415/article/details/111241088