Spring Cloud 是目前最火的微服務框架,Feign 作為基礎組件之一,在 Spring Cloud 體系中發揮了重要的作用。
一、FeignClient注解
FeignClient注解被@Target(ElementType.TYPE)修飾,表示FeignClient注解的作用目標在接口上
//@FeignClient(value = "fast-maindata-service",contextId = "MaindataServiceClient")
@FeignClient(url = "47.100.79.142:30041",name = "MaindataServiceClient")
public interface MaindataServiceClient extends IMaindataPharmacyController {
}
聲明接口之后,在代碼中通過@Resource注入之后即可使用。@FeignClient標簽的常用屬性如下:
- name:指定FeignClient的名稱,如果項目使用了Ribbon,name屬性會作為微服務的名稱,用於服務發現
- url: url一般用於調試,可以手動指定@FeignClient調用的地址
- decode404:當發生http 404錯誤時,如果該字段位true,會調用decoder進行解碼,否則拋出FeignException
- configuration: Feign配置類,可以自定義Feign的Encoder、Decoder、LogLevel、Contract
- fallback: 定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback指定的類必須實現@FeignClient標記的接口
- fallbackFactory: 工廠類,用於生成fallback類示例,通過這個屬性我們可以實現每個接口通用的容錯邏輯,減少重復的代碼
- path: 定義當前FeignClient的統一前綴
@FeignClient(name = "github-client",
url = "https://api.github.com",
configuration = GitHubExampleConfig.class,
fallback = GitHubClient.DefaultFallback.class)
public interface GitHubClient {
@RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
String searchRepo(@RequestParam("q") String queryStr);
/**
* 容錯處理類,當調用失敗時,簡單返回空字符串
*/
@Component
public class DefaultFallback implements GitHubClient {
@Override
public String searchRepo(@RequestParam("q") String queryStr) {
return "";
}
}
}
在使用fallback屬性時,需要使用@Component注解,保證fallback類被Spring容器掃描到,GitHubExampleConfig內容如下:
@Configuration
public class GitHubExampleConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
在使用FeignClient時,Spring會按name創建不同的ApplicationContext,通過不同的Context來隔離FeignClient的配置信息,在使用配置類時,不能把配置類放到Spring App Component scan的路徑下,否則,配置類會對所有FeignClient生效.
關於調用目前有兩種:
1、接口提供方在注冊中心。
如果服務提供方已經注冊到注冊中心了,那么name或者value的值為:服務提供方的服務名稱。必須為所有客戶端指定一個name或者value
@FeignClient(value="run-product",fallback = ProductClientServiceFallBack.class)
2、單獨的一個http接口,接口提供方沒有注冊到注冊中心。
@FeignClient(name="runClient11111",url="localhost:8001")
此處name的值為:調用客戶端的名稱。
以上兩種方式都能正常調用。name可以為注冊中心的實例名稱,加上url屬性時,name的值就與注冊中心實例名稱無關。至於url屬性和name屬性的關系請指導的大佬們留言呀。
