记一次spring-spi机制下少包导致的启动问题

文章讲述了在升级easy-poi包后,由于缺失spring-cloud-netflix-hystrix依赖,导致服务启动失败的问题。通过分析日志、理解SPI机制,发现@EnableCircuitBreaker注解找不到实现,最终找到原因是缺少对应的jar包。添加缺失的依赖后,解决了问题。
摘要由CSDN通过智能技术生成

SPI (Service Provider Interface)


Java SPI, META-INF/services/com.example.MyService:com.example.MyServiceImpl
Dobbo SPI,META-INF/dubbo/com.example.MyService:impl1=com.example.MyServiceImpl1
SpringSPI,META-INF/spring.factories:com.example.MyService=com.example.MyServiceImpl


问题背景和现象

最近同事由于新需求需要使用easy-poi包的其他功能,升级了版本,第二天的版本部分服务启动失败。日志如下:
Application run failed java.lang.IllegalStateException:
Annotation @EnableCircuitBreaker found, but there are no implementations. Did you forget to include a starter?
在这里插入图片描述

排查过程

之前没有遇到过类似问题,更不清楚@EnableCircuitBreaker是干什么,属于哪个包。网上的解决方案都是引入"spring-cloud-starter-netflix-hystrix"依赖即可。
不过问题就在于,我们环境里是有这个包spring-cloud-starter-netflix-hystrix-2.2.5.RELEASE.jar的,这就尴尬了。我不禁对这些博主有些失望,进一步的在帖子中找到stack-over-flow的帖子
在这里插入图片描述

帖子主要意思:

  1. 这个问题的原因是应用在尝试加载一些spring集成的class文件时候没有找到导致的
  2. 你可以深入到报错的堆栈信息中找到带有"AutoConfiguration"字样的错误,以定位具体缺失的class
  3. 你还可以通过开启spring的debug日志去看到底在自动配置些什么东西?一旦定位到之后,可以通过@EnableAutoConfiguration注解进行排除

那么我又一步一步的去做。
开始尝试在堆栈中找AutoConfiguration,并没有。
开启debug之后,仍然没看到比较有价值的日志。

没有办法,只有去代码中找一下哪里在调用。幸好IDEA牛逼,可以直接查询jar包中的类名,直接定位到这个注解@EnableCircuitBreaker ,只找到一个地方有引用:
在这里插入图片描述

第一个就是注解本身,看下第二个:
在这里插入图片描述
看似有关系,但是又不知道关系在哪里。再次点击EnableCircuitBreaker注解查找引用的地方(注意,IDEA的2022.1.2社区版点不过去):
在这里插入图片描述
到这里就有点快到出口的感觉了,这个spring.factories文件看着就很眼熟,这不就是SPI机制嘛。
EnableCircuitBreaker是属于spring-cloud-commons-2.1.0.RELEASE.jar包;
HystrixCircuitBreakerConfiguration属于spring-cloud-netflix-hystrix-2.1.3.RELEASE.jar包;
而HystrixCircuitBreakerConfiguration类根据Spring的SPI机制,作为EnableCircuitBreaker的具体实现,在启动的时候因为EnableCircuitBreaker被加载,这时候需要加载它的具体实现类,可以由于缺少spring-cloud-netflix-hystrix这个包,所以根本无从加载,所以报了Annotation @EnableCircuitBreaker found, but there are no implementations. Did you forget to include a starter?这个错误,现在看来还是很贴心了。

那么,为什么会存在有spring-cloud-starter-netflix-hystrix包却没有spring-cloud-netflix-hystrix包的情况呢?starter不是包含了具体的包吗?后面找到原因是由于有同事删除了spring-cloud-netflix-hystrix的依赖,由于是使用的pom的多行注释,所以在使用find命令排查的时候误以为还在。

于是乎,将spring-cloud-netflix-hystrix包拷贝到环境中,good,不报这个注解的错误了,开始报其他错误了(因为spring-cloud-netflix-hystrix依赖hystrix-core-1.5.18.jar等包,依次拷贝过去就ok)。

至此,问题原因清楚了:SPI实现类缺失导致的问题


总结

这里贴一个SPI的文章,JDK-SPI、Spring-SPI、Dubbo-SPI三种spi机制简要说明,这三种SPI的形式和特点各不相同。

在开发过程中遇到问题,一定不要放过,只要深入排查跟踪,才会有收获和进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值