Feign集成Hystric報錯


Feign集成Hystric報錯

問題:在feign上使用hystric時一直報錯。

@FeignClient(name = "provider-server", fallback = ProviderClient.ProviderClientFallback.class)
@RequestMapping("/api/v1/provider")
public interface ProviderClient {

    @GetMapping("/port")
    String port();

    class ProviderClientFallback implements ProviderClient {

        @Override
        public String port() {
            return "provider error";
        }

    }
}

當時想OpenFeign會代理聲明的接口生成實現類,再創建ProviderClientFallback,spring注入時不是會出問題嗎...

猜測feign會自己加載 fallback = ProviderClient.ProviderClientFallback.class,創建時間,綁定fallback。可是。。。

Caused by: java.lang.IllegalStateException: No fallback instance of type class com.zuizui.cloud.feign.feign.ProviderClient$ProviderClientFallback found for feign client provider-server

於是查文檔發現:

When using Feign with Hystrix fallbacks, there are multiple beans in the ApplicationContext of the same type. This will cause @Autowired to not work because there isn’t exactly one bean, or one marked as primary. To work around this, Spring Cloud Netflix marks all Feign instances as @Primary, so Spring Framework will know which bean to inject. In some cases, this may not be desirable. To turn off this behavior set the primary attribute of @FeignClient to false.

Spring Cloud Netflix將所有Feign實例標記為@Primary,因此Spring Framework將知道要注入哪個bean

@FeignClient(name = "hello", primary = false)
public interface HelloClient {
	// methods here
}

所有默認注入的都是代理接口實例,不會是xxxfallback實例。除非指定primary = false

現在嘗試將ProviderClientFallback實例化,加上@Component

@FeignClient(name = "provider-server", fallback = ProviderClient.ProviderClientFallback.class)
@RequestMapping("/api/v1/provider")
public interface ProviderClient {

    @GetMapping("/port")
    String port();

  	@Component
    class ProviderClientFallback implements ProviderClient {

        @Override
        public String port() {
            return "provider error";
        }

    }
}

產生新的問題:interface和url同時mapper到了同一個地址。

Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'com.zuizui.cloud.feign.feign.ProviderClient' method 
public abstract java.lang.String com.zuizui.cloud.feign.feign.ProviderClient.port()
to {[/api/v1/provider/port],methods=[GET]}: There is already 'providerClient.ProviderClientFallback' bean method
public java.lang.String com.zuizui.cloud.feign.feign.ProviderClient$ProviderClientFallback.port() mapped

Url mapping 存在了繼承關系。嘗試將@RequestMapping("/api/v1/provider")放到方法聲明上

@FeignClient(name = "provider-server", fallback = ProviderClient.ProviderClientFallback.class)
public interface ProviderClient {

    @GetMapping("/api/v1/provider/port")
    String port();

  	@Component
    class ProviderClientFallback implements ProviderClient {

        @Override
        public String port() {
            return "provider error";
        }

    }
}

啟動成功。

(優雅)解決方法:2

可以注意到RequestMapping中的value是“/conputer/add”,一般我們在spring mvc中,前面一致的都會放在class上,但是如果把@RequestMapping(value = “/computer”)放在接口上的話,還是會報錯。
進入FeignClient注解里看了下屬性,有一個path屬性,是用來表示接口內所有方法請求的前綴的,而不是像springmvc,在接口上配置前綴@RequestMapping
https://my.oschina.net/u/2000675/blog/2244769

修改代碼

@FeignClient(name = "provider-server", fallback = ProviderClient.ProviderClientFallback.class, path="/api/v1/provider")
public interface ProviderClient {

    @GetMapping("/port")
    String port();

  	@Component
    class ProviderClientFallback implements ProviderClient {

        @Override
        public String port() {
            return "provider error";
        }

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM