最近公司的项目基于Jhipster开发,在享受到开发便利的同时,也遇到许多糟心事,Elasticsearch的各个微服务整合,便是之一。
Jhipster框架的不便利之处,在于没有一个统一的parent工程来管理所有的公共jar包,这样每开一个微服务,如果需要用到前一个服务的某些功能,便需要在新的服务引入这些jar包和配置,极其繁琐。
稍不留神,便会出错。Elasticsearch的新工程引入,便是笔者遇到的问题之一。
虽然是针对Jhipster框架下的问题,但是整个知识点还是不出于springcloud和springboot的范畴,相信对大家处理类似的问题,会有触类旁通之效。
大家请看,下面便是启动错误显示,大意便是,容器中本应存在的bean,没有被初始化。
***************************
APPLICATION FAILED TO START
***************************Description:
Parameter 1 of method elasticsearchTemplate in com.bmw.tsic.ai.config.ElasticsearchConfiguration required a bean of type 'org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'elasticsearchConverter' in 'ElasticsearchDataAutoConfiguration' not loaded because auto-configuration 'ElasticsearchDataAutoConfiguration' was excludedAction:
Consider revisiting the entries above or defining a bean of type 'org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter' in your configuration.
反应在代码种的实际情况,如下(注意红色下划线便是报错,Could not autowire. No beans of 'ElasticsearchConverter' type found.):
也就是ElasticsearchConverter和SimpleElasticsearchMappingContext类型的两个bean,在ioc容器中,并不存在。
为什么会出现这种情况呢,笔者找到了基于spring-data-jest的自动配置文件:
@Configuration @AutoConfigureAfter({ElasticsearchJestAutoConfiguration.class}) public class ElasticsearchJestDataAutoConfiguration { public ElasticsearchJestDataAutoConfiguration() { } @Bean @ConditionalOnMissingBean public ElasticsearchOperations elasticsearchTemplate(JestClient client) { return new JestElasticsearchTemplate(client); } @Bean @ConditionalOnMissingBean public ElasticsearchConverter elasticsearchConverter(SimpleElasticsearchMappingContext mappingContext) { return new MappingElasticsearchConverter(mappingContext); } @Bean @ConditionalOnMissingBean public SimpleElasticsearchMappingContext mappingContext() { return new SimpleElasticsearchMappingContext(); } }
可以发现,ioc容器内未被发现的两个bean是有被自动注入容器中的,那为什么我的新工程中确显示不出来呢?
在对比了一番新工程的pom文件之后,我尴尬的发现,原来是工程引入spring-data-jest的starter没有被引入,导致本该自动注入的bean没有被自动装配到容器中。
我只引入了一个
<dependency> <groupId>com.github.vanroy</groupId> <artifactId>spring-data-jest</artifactId> <version>3.2.5.RELEASE</version> <scope>compile</scope> </dependency>
而正确的做法应该是:
<dependency> <groupId>com.github.vanroy</groupId> <artifactId>spring-boot-starter-data-jest</artifactId> <version>3.2.5.RELEASE</version> <scope>compile</scope> </dependency>
我们仔细深入,ctrl+鼠标左键,点击进入starter的pom文件,可以发现,starter本身是包含spring-data-jest这个jar包的,也就是说只需要引入一个start包就可以直接运行了。
这也符合springboot关于自动配置后开箱即用的思想。
然后我回转到旧工程,发现了以前同事的神奇操作,他同时引入了spring-data-jest和它的start包,然后还没有放一起,我把pom文件拷贝到新工程的时候,由于没有仔细观察,加上spring-data-jest的依赖上还写了一个引入elastic的注释,就大意了。
导致新的工程总是跑不起来。
由于项目过程中事太多太紧急,没有深究,项目完成之后,才有时间重现解决一下。