记fallbackFactory引用到远程接口中报错java.lang.IllegalStateException: No fallbackFactory instance of type class
这个问题放了好久都没有管,今天解决了记录一下(本来以为是什么很深奥的 bug,结果发现是自己太菜了)
Caused by: java.lang.IllegalStateException: No fallbackFactory instance of type class com.*.*.*.api.factory.RemoteFallbackFactory found for feign client remoteService
目前项目使用的是 SpringCloud,module 配置是两个无启动类的 module 作为公共模块,一个 API 做为所有 module 的远程接口模块,还有一个 common 作为配置以及基础工具模块
之前自己公司项目的 FeignClient 都是在启动类同目录下,所以在启动类加一个@EnableFeignClients注解,添加个扫描包就行,而且没有配置过 fallbackFactory,所以从来没有接触过这种问题。
实际上这种问题的出现,确实就是 spring 没有扫描到这个 bean,虽然已经加了@Component注解,但是由于是跟启动类不同 module,所以这个类扫描不到。
那么问题来了,springboot 怎么样去扫描组件呢?
查看@SpringBootApplication的源码可以看到
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
其中@ComponentScan这个注解是扫描@SpringBootApplication所在包下的所有@Component注解标记的 bean,并注册到 Spring 容器中。这里源码就省略了,基本就是类加载器加载了 class 文件,然后扫描其中是否有注解。
那如果想要注册的 bean 不在包扫描路径下怎么办?
(1)在主类上使用 @Import 注解(本次不做解释)
(2)使用 spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.*.*.*.api.factory.RemoteUserFallbackFactory,\
com.*.*.*.api.factory.RemoteLogFallbackFactory
spring.factories 文件是帮助 spring-boot 项目包以外的 bean(即在 pom 文件中添加依赖中的 bean)注册到 spring-boot 项目的 spring 容器。由于
@ComponentScan
注解只能扫描 spring-boot 项目包内的 bean 并注册到 spring 容器中,因此需要@EnableAutoConfiguration
注解来注册项目包外的 bean。而 spring.factories 文件,则是用来记录项目包外需要注册的 bean 类名。
具体参考: