摘要:繼承支持通過單繼承接口支持樣板,這允許將通用操作分組為方便的基本接口。,記錄基本信息以及請求和響應。例如,類定義參數和以下客戶端使用注解使用類
聲明式REST客戶端:Feign
Feign是一個聲明式的Web服務客戶端,它使編寫Web服務客戶端變得更容易,要使用Feign,請創建一個接口并對其進行注解,它具有可插拔的注解支持,包括Feign注解和JAX-RS注解,Feign還支持可插拔編碼器和解碼器。Spring Cloud增加了對Spring MVC注解的支持,并使用了Spring Web中默認使用的相同HttpMessageConverters,Spring Cloud集成了Ribbon和Eureka,在使用Feign時提供負載均衡的http客戶端。
如何包含Feign要在項目中包含Feign,請使用包含組名為org.springframework.cloud和工件名為spring-cloud-starter-openfeign的啟動器。
spring boot應用示例
@SpringBootApplication @EnableFeignClients public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
StoreClient.java
@FeignClient("stores") public interface StoreClient { @RequestMapping(method = RequestMethod.GET, value = "/stores") ListgetStores(); @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json") Store update(@PathVariable("storeId") Long storeId, Store store); }
在@FeignClient注解中,String值(上面的“stores”)是一個任意客戶端名稱,用于創建Ribbon負載均衡器,你還可以使用url屬性指定URL(絕對值或僅指定主機名),應用程序上下文中bean的名稱是接口的完全限定名稱,要指定自己的別名值,可以使用@FeignClient注解的qualifier值。
上面的Ribbon客戶端將想要發現“stores”服務的物理地址,如果你的應用程序是Eureka客戶端,那么它將解析Eureka服務注冊表中的服務,如果你不想使用Eureka,只需在外部配置中配置服務器列表。
覆蓋Feign默認值Spring Cloud的Feign支持的核心概念是命名客戶端,每個feign客戶端都是一個組件集成的一部分,這些組件協同工作以按需聯系遠程服務器,并且集成有一個名稱,作為使用@FeignClient注解的應用程序開發人員可以使用這個名稱。Spring Cloud使用FeignClientsConfiguration按需為每個命名客戶端創建一個新的集成作為ApplicationContext,這包含(除其他外)feign.Decoder、feign.Encoder和feign.Contract,可以使用@FeignClient注解的contextId屬性覆蓋該集成的名稱。
Spring Cloud允許你通過使用@FeignClient聲明其他配置(在FeignClientsConfiguration之上)來完全控制feign客戶端,例如:
@FeignClient(name = "stores", configuration = FooConfiguration.class) public interface StoreClient { //.. }
在這種情況下,客戶端由FeignClientsConfiguration中已有的組件以及FooConfiguration中的任何組件組成(后者將覆蓋前者)。
FooConfiguration不需要使用@Configuration注解,但是,如果是,則注意將其從任何包含此配置的@ComponentScan中排除,因為它將成為feign.Decoder、feign.Encoder、feign.Contract等的默認源。這可以通過將其放在任何@ComponentScan或@SpringBootApplication的多帶帶的非重疊包中來避免,也可以在@ComponentScan中明確排除。
現在不推薦使用serviceId屬性,而是使用name屬性。
使用@FeignClient注解的contextId屬性除了更改ApplicationContext集成的名稱,它將覆蓋客戶端名稱的別名,它將用作為該客戶端創建的配置bean名稱的一部分。
以前,使用url屬性不需要name屬性,現在需要使用name。
name和url屬性支持占位符。
@FeignClient(name = "${feign.name}", url = "${feign.url}") public interface StoreClient { //.. }
Spring Cloud Netflix默認為feign(BeanType beanName:ClassName)提供以下bean:
Decoder feignDecoder:ResponseEntityDecoder(包裝SpringDecoder)
Encoder feignEncoder:SpringEncoder
Logger feignLogger:Slf4jLogger
Contract feignContract:SpringMvcContract
Feign.Builder feignBuilder:HystrixFeign.Builder
Client feignClient:如果啟用了Ribbon,則它是LoadBalancerFeignClient,否則使用默認的feign客戶端。
可以通過將feign.okhttp.enabled或feign.httpclient.enabled分別設置為true,并將它們放在類路徑上來使用OkHttpClient和ApacheHttpClient feign客戶端,你可以通過在使用Apache時提供ClosableHttpClient或在使用OK HTTP時提供OkHttpClient的bean來定制使用的HTTP客戶端。
Spring Cloud Netflix默認情況下不為feign提供以下bean,但仍然從應用程序上下文中查找這些類型的bean以創建feign客戶端:
Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection
SetterFactory
創建其中一種類型的bean并將其放在@FeignClient配置中(如上面的FooConfiguration)允許你覆蓋所描述的每個bean,例如:
@Configuration public class FooConfiguration { @Bean public Contract feignContract() { return new feign.Contract.Default(); } @Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { return new BasicAuthRequestInterceptor("user", "password"); } }
這將使用feign.Contract.Default替換SpringMvcContract,并將RequestInterceptor添加到RequestInterceptor的集合中。
@FeignClient也可以使用配置屬性進行配置。
application.yml
feign: client: config: feignName: connectTimeout: 5000 readTimeout: 5000 loggerLevel: full errorDecoder: com.example.SimpleErrorDecoder retryer: com.example.SimpleRetryer requestInterceptors: - com.example.FooRequestInterceptor - com.example.BarRequestInterceptor decode404: false encoder: com.example.SimpleEncoder decoder: com.example.SimpleDecoder contract: com.example.SimpleContract
可以以與上述類似的方式在@EnableFeignClients屬性defaultConfiguration中指定默認配置,不同之處在于此配置將適用于所有feign客戶端。
如果你更喜歡使用配置屬性來配置所有@FeignClient,則可以使用default feign名稱創建配置屬性。
application.yml
feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 loggerLevel: basic
如果我們同時創建@Configuration bean和配置屬性,配置屬性將獲勝,它將覆蓋@Configuration值,但是,如果要將優先級更改為@Configuration,則可以將feign.client.default-to-properties更改為false。
如果需要在RequestInterceptor中使用ThreadLocal綁定變量,則需要將Hystrix的線程隔離策略設置為“SEMAPHORE”或在Feign中禁用Hystrix。
application.yml
# To disable Hystrix in Feign feign: hystrix: enabled: false # To set thread isolation to SEMAPHORE hystrix: command: default: execution: isolation: strategy: SEMAPHORE
如果我們想要創建具有相同名稱或URL的多個feign客戶端,以便它們指向同一服務器但每個都具有不同的自定義配置,那么我們必須使用@FeignClient的contextId屬性,以避免這些配置bean的名稱沖突。
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class) public interface FooClient { //.. }
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class) public interface BarClient { //.. }手動創建Feign客戶端
在某些情況下,可能需要以使用上述方法無法實現的方式自定義Feign客戶端,在這種情況下,你可以使用Feign Builder API創建客戶端。下面是一個示例,它創建兩個具有相同接口的Feign客戶端,但使用多帶帶的請求攔截器配置每個客戶端。
@Import(FeignClientsConfiguration.class) class FooController { private FooClient fooClient; private FooClient adminClient; @Autowired public FooController(Decoder decoder, Encoder encoder, Client client, Contract contract) { this.fooClient = Feign.builder().client(client) .encoder(encoder) .decoder(decoder) .contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("user", "user")) .target(FooClient.class, "http://PROD-SVC"); this.adminClient = Feign.builder().client(client) .encoder(encoder) .decoder(decoder) .contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) .target(FooClient.class, "http://PROD-SVC"); } }
在上面的示例中,FeignClientsConfiguration.class是Spring Cloud Netflix提供的默認配置。
PROD-SVC是客戶端將向其發出請求的服務的名稱。
Feign Contract對象定義了哪些注解和值在接口上是有效的,自動裝配的Contract bean提供對SpringMVC注解的支持,而不是默認的Feign原生注解。Feign Hystrix支持
如果Hystrix位于類路徑并且feign.hystrix.enabled=true,則Feign將使用斷路器包裝所有方法,返回com.netflix.hystrix.HystrixCommand也可用,這允許你使用反應模式(通過調用.toObservable()或.observe()或異步使用(通過調用.queue())。
要在每個客戶端的基礎上禁用Hystrix支持,請創建一個帶有“prototype”范圍的vanilla F??eign.Builder,例如:
@Configuration public class FooConfiguration { @Bean @Scope("prototype") public Feign.Builder feignBuilder() { return Feign.builder(); } }
在Spring Cloud Dalston發布之前,如果Hystrix在類路徑上,Feign會默認將所有方法包裝在斷路器中,Spring Cloud Dalston中更改了此默認行為,轉而采用了選擇加入方法。
Feign Hystrix FallbackHystrix支持回退的概念:在電路打開或出現錯誤時執行的默認代碼路徑,要為給定的@FeignClient啟用回退,請將fallback屬性設置為實現回退的類名,你還需要將實現聲明為Spring bean。
@FeignClient(name = "hello", fallback = HystrixClientFallback.class) protected interface HystrixClient { @RequestMapping(method = RequestMethod.GET, value = "/hello") Hello iFailSometimes(); } static class HystrixClientFallback implements HystrixClient { @Override public Hello iFailSometimes() { return new Hello("fallback"); } }
如果需要訪問產生回退觸發器的原因,可以使用@FeignClient中的fallbackFactory屬性。
@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) protected interface HystrixClient { @RequestMapping(method = RequestMethod.GET, value = "/hello") Hello iFailSometimes(); } @Component static class HystrixClientFallbackFactory implements FallbackFactory{ @Override public HystrixClient create(Throwable cause) { return new HystrixClient() { @Override public Hello iFailSometimes() { return new Hello("fallback; reason was: " + cause.getMessage()); } }; } }
在Feign中實現回退以及Hystrix回退如何工作都有一定的限制,返回com.netflix.hystrix.HystrixCommand和rx.Observable的方法目前不支持回退。Feign和@Primary
當與Hystrix回退一起使用Feign時,ApplicationContext中有相同類型的多個bean,這將導致@Autowired無法工作,因為沒有一個明確的bean或一個標記為primary的bean。為了解決這個問題,Spring Cloud Netflix將所有Feign實例標記為@Primary,因此Spring Framework將知道要注入哪個bean,在某些情況下,這可能并不理想,要關閉此行為,請將@FeignClient的primary屬性設置為false。
@FeignClient(name = "hello", primary = false) public interface HelloClient { // methods here }Feign繼承支持
Feign通過單繼承接口支持樣板api,這允許將通用操作分組為方便的基本接口。
UserService.java
public interface UserService { @RequestMapping(method = RequestMethod.GET, value ="/users/{id}") User getUser(@PathVariable("id") long id); }
UserResource.java
@RestController public class UserResource implements UserService { }
UserClient.java
package project.user; @FeignClient("users") public interface UserClient extends UserService { }
通常不建議在服務器和客戶端之間共享接口,它引入了緊耦合,并且實際上也不能以其當前形式使用Spring MVC(方法參數映射不會被繼承)。
Feign請求/響應壓縮你可以考慮為你的Feign請求啟用請求或響應GZIP壓縮,你可以通過啟用以下屬性之一來執行此操作:
feign.compression.request.enabled=true feign.compression.response.enabled=true
Feign請求壓縮為你提供類似于你為Web服務器設置的設置:
feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048
通過這些屬性,你可以選擇壓縮介質類型和最小請求閾值長度。
Feign記錄日志為每個創建的Feign客戶端創建一個記錄器,默認情況下,記錄器的名稱是用于創建Feign客戶端的接口的完整類名,Feign日志記錄僅響應DEBUG級別。
application.yml
logging.level.project.user.UserClient: DEBUG
你可以為每個客戶端配置Logger.Level對象,告訴Feign要記錄多少,選擇是:
NONE,沒有記錄(DEFAULT)。
BASIC,僅記錄請求方法和URL以及響應狀態代碼和執行時間。
HEADERS,記錄基本信息以及請求和響應headers。
FULL,記錄請求和響應的headers、body和元數據。
例如,以下內容將Logger.Level設置為FULL:
@Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }Feign @QueryMap支持
OpenFeign @QueryMap注解為POJO提供了支持,可用作GET參數映射,不幸的是,默認的OpenFeign QueryMap注解與Spring不兼容,因為它缺少value屬性。
Spring Cloud OpenFeign提供等效的@SpringQueryMap注解,用于將POJO或Map參數注解為查詢參數映射。
例如,Params類定義參數param1和param2:
// Params.java public class Params { private String param1; private String param2; // [Getters and setters omitted for brevity] }
以下feign客戶端使用@SpringQueryMap注解使用Params類:
@FeignClient("demo") public class DemoTemplate { @GetMapping(path = "/demo") String demoEndpoint(@SpringQueryMap Params params); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74163.html
摘要:對進行了封裝,使其支持標準注解和。可以與和組合使用以支持負載均衡。中使用當我們搭建好注冊中心之后,就是需要將自己的服務注冊到中,然后別的服務可以直接調用。 JAVA 項目中接口調用怎么做 ? Httpclient Okhttp Httpurlconnection RestTemplate 上面是最常見的幾種用法,我們今天要介紹的用法比上面的更簡單,方便,它就是 Feign Feig...
摘要:集群系統中的單個計算機通常稱為節點,通常通過局域網連接,但也有其它的可能連接方式。這樣就高興了,可以專心寫自己的,前端就專門交由小周負責了。于是,小周和就變成了協作開發。都是為了項目正常運行以及迭代。 一、前言 只有光頭才能變強 認識我的朋友可能都知道我這陣子去實習啦,去的公司說是用SpringCloud(但我覺得使用的力度并不大啊~~)... 所以,這篇主要來講講SpringClou...
摘要:集群系統中的單個計算機通常稱為節點,通常通過局域網連接,但也有其它的可能連接方式。這樣就高興了,可以專心寫自己的,前端就專門交由小周負責了。于是,小周和就變成了協作開發。都是為了項目正常運行以及迭代。 一、前言 只有光頭才能變強 認識我的朋友可能都知道我這陣子去實習啦,去的公司說是用SpringCloud(但我覺得使用的力度并不大啊~~)... 所以,這篇主要來講講SpringClou...
閱讀 2772·2021-10-14 09:42
閱讀 827·2021-10-11 10:57
閱讀 773·2019-08-30 15:54
閱讀 1914·2019-08-30 13:50
閱讀 1686·2019-08-30 11:19
閱讀 932·2019-08-29 12:38
閱讀 1425·2019-08-26 11:51
閱讀 1388·2019-08-26 10:48