最近在复盘查看项目之前的代码,查看到项目中对于网关日志信息集成了es的使用,刚好想学习一下!

yml文件中有针对es服务的配置信息,但是在项目代码中没有看到针对es的配置信息的配置类,所以就在

想是如何调用到es服务的呢?

springboot 读es_spring


查看了许久,想到关于springboot的自动装配机制,所以去查看spring boot源代码,找到了es的自动配置类信息,所以记录一下!先自我回顾一下spring boot启动自动装配的机制原理!

springboot启动类上的核心注解@SpringBootApplication是关键,这是一个组合注解,主要包含了@SpringBootConfiguration和@EnableAutoConfiguration这两个注解为核心

springboot 读es_springboot 读es_02


@SpringBootConfiguration注解点进去查看,可以看到里面包含了spring的注解@Configuration,既代表自己是一个Spring的配置类!

springboot 读es_spring boot_03


springboot实现自动装配机制重点是@EnableAutoConfiguration注解,点进去看到也是一个组合注解,包含@AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class})注解!

springboot 读es_spring_04


最关键是@Import({AutoConfigurationImportSelector.class})注解,会导入一个AutoConfigurationImportSelector类,这个类中有一个getCandidateConfigurations()方法会获取所有的配置信息!

这个方法用来获取所有候选的配置,那这些候选配置又是从哪来的呢?带着问题看源码!

springboot 读es_java_05


它返回了一个List是由loadFactoryNames()方法返回的,其中传入了一个getSpringFactoriesLoaderFactoryClass(),可以看下这个方法的代码!

springboot 读es_spring_06


我们看到返回的是EnableAutoConfiguration的class类,也就是说,它实际上返回的就是标注了这个类的所有包。那标注了这个类的包不就是@SpringBootApplication吗?

所以可以说:绕来绕去就是为了将启动类所需的所有资源导入。

接着往下看getCandidateConfigurations()方法,它其中还有这么一条语句,是一条断言:

springboot 读es_配置信息_07


这个断言的意思是,configurations必须非空,否则就打印一段话,No auto configuration classes found in META-INF/spring.factories,那反过来如果这个集合不为空,是不是就代表找到了这个spring.factories并且会去加载这个文件中的内容呢?

带着问题找到META-INF/spring.factories文件:

springboot 读es_spring boot_08


到这里,我们可以总结出springboot的自动装配原理:当SpringBoot项目启动的时候,会先导入AutoConfigurationImportSelector类,这个类会帮我们选择所有候选的配置,我们需要导入的配置都是SpringBoot帮我们写好的一个一个的配置类,那么这些配置类的位置,存在与META-INF/spring.factories文件中,通过这个文件,Spring可以找到这些配置类的位置,于是去加载其中的配置。当然这些配置类也不是所有的都会加载,每个配置类上有注解@ConditionalOnClass和@ConditionalOnProperty,所以springboot会按需加载配置类!

同时在这里面找到了ElasticsearchAutoConfiguration配置类,点进去查看:

springboot 读es_spring boot_09


并且在上面的注解@ConditionalOnProperty(prefix = “spring.data.elasticsearch”,name = {“cluster-nodes”},matchIfMissing = false)找到了开头yml配置文件中es的配置信息的key,所以es的配置信息初始化在项目启动的时候就已经自动装配完成了,使用时,只需要在pom文件中引入spring-data-elasticsearch的jar包,就可以通过ElasticSearchTemplate进行调用使用了!

以上是工作中遇到的问题,并通过源码查看得出的自己的一些理解,记录一下所学,如有不对的地方,欢迎大家指出!