美文网首页SpringCloudJavaWeb 知识点
2018-03-21 SpringCloud Feign Fal

2018-03-21 SpringCloud Feign Fal

作者: 一杯半盏 | 来源:发表于2018-03-21 20:46 被阅读490次

    问题

    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则是匹配的。

    全文完。

    最近遇到的问题,都特别诡异,但问题终将被解决

    相关文章

      网友评论

      • 高山之水:spring cloud就是诡异的东西 习惯了就好了 哈哈

      本文标题:2018-03-21 SpringCloud Feign Fal

      本文链接:https://www.haomeiwen.com/subject/poenqftx.html