问题
No fallback instance of type ... found for feign client
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderProcessorBiz':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.xx.xx.service.IRemoteBridgeService com.xx.xx.biz.order.OrderProcessorBiz.remoteBridgeService;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.xx.xx.service.IRemoteBridgeService':
FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException:
No fallback instance of type class com.xx.xx.HystrixClientFallback found for feign client http://172.16.2.163:8001
Caused by: java.lang.IllegalStateException: No fallback instance of type class com.xx.xx.HystrixClientFallback found for feign client http://172.16.2.163:8001
通常需要确认配置内容
- 开启hystrix
feign.hystrix.enabled=true
- Fallback类需要注解
@Component
依旧不行?
跟踪代码发现 是因为对FeignClient 这个接口做了AOP切面。
@Pointcut("execution(* com.xx.xx.service.IR*.*(..))")
public void remoteCall() {
}
Trace日志看到这么一行:
[DEBUG] [17:50:22.410][JdkDynamicAopProxy][117]:Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [com.xx.xx.service.HystrixClientFallback@32354b00]
然后考虑是不是因为Spring AOP动态代理默认为 JDK动态代理。
切面还是要切的,Fallback也不能放弃。因为调用的是接口,无论如何都要被切。
换成cglib后,问题成功解决。
@EnableAspectJAutoProxy(proxyTargetClass = true)
这里给一个链接:
https://stackoverflow.com/questions/33110661/spring-aop-bean-injection-bug
原理
SpringAOP 的动态代理有两种实现,JDK动态代理,和Cglib。
Spring默认使用 JDK动态代理。
当类至少实现了一个接口时,使用JDK动态代理。上文的Feign的Fallback类正好是这样。
至于究竟为什么cglib可以成功,就不去深究了,方案就两个,非此即彼。
至于为什么 找不到 fallback instance?
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<String>();
// Check all bean definitions.
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// In case of FactoryBean, match object created by FactoryBean.
boolean isFactoryBean = isFactoryBean(beanName, mbd);
boolean matchFound = (allowEagerInit || !isFactoryBean || containsSingleton(beanName)) &&
(includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type);
......
//以下代码省略
问题出现在isTypeMatch
isTypeMatch.png这里isTypeMatch 返回了false,因为骗不过JVM类型检查。当使用cglib则是匹配的。
全文完。
最近遇到的问题,都特别诡异,但问题终将被解决
网友评论