记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类名。

 

具体参考:

spring.factories 的妙用

SpringBoot中spring.factories文件的作用

上一篇:Spring AOP 源码刨析


下一篇:「初识」SpringBoot 属性注入的方式