背景
我参加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或者已经工作的开发者们有帮助。