Spring Cloud踩坑(三)添加了Fallback以后No fallback instance of type ... found for feign client

题记:我遇到的问题在上一篇解决方案中,这个有待回看,但是感觉挺有道理,临时准载下来!

问题

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

通常需要确认配置内容

  1. 开启hystrix
feign.hystrix.enabled=true
  1. 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则是匹配的。




原文:https://www.jianshu.com/p/c8210d878e96

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值