最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud Feign 自定義配置(重試、攔截與錯誤碼處理) 代碼實踐

 更新時間:2020年08月26日 09:28:50   作者:上帝愛吃蘋果-  
這篇文章主要介紹了Spring Cloud Feign 自定義配置(重試、攔截與錯誤碼處理) 實踐,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

基于 spring-boot-starter-parent 2.1.9.RELEASE, spring-cloud-openfeign 2.1.3.RELEASE

引子

Feign 是一個聲明式、模板化的HTTP客戶端,簡化了系統(tǒng)發(fā)起Http請求。創(chuàng)建它時,只需要創(chuàng)建一個接口,然后加上FeignClient注解,使用它時,就像調(diào)用本地方法一樣,作為開發(fā)者的我們完全感知不到這是在調(diào)用遠程的方法,也感知不到背后發(fā)起了HTTP請求:

/**
 * @author axin
 * @suammry xx 客戶端
 */
@FeignClient(value = "xxClient",url = "${xx.host:www.axin.com}")
public interface DemoClient {

  @PostMapping(value = "/xxx/url", headers = "Content-Type=application/json"})
  yourResponse requestHTTP(@RequestBody JSONObject param);

}

上述的代碼就是一個定義一個Feign HTTP 客戶端,在其他類中只需要 @Autowired DemoClient,就可以像調(diào)用本地方法一樣發(fā)起HTTP請求。

介紹就到這,接下來進入主題,因為 FeignClient 將發(fā)起HTTP請求與解析返回報文都做了包裝,如果你的業(yè)務場景需要定制一些調(diào)用機制,比如:

  • 我想在發(fā)起請求響應超時失敗時自動重試 —— 自定義重試機制
  • 我想單獨對某些異常的HTTP狀態(tài)碼特殊處理 —— 自定義ErrorDecoder
  • 服務端接口需要驗證簽名,所以我方在發(fā)起請求時要生成簽名然后傳過去 —— 定義 Fegin 攔截器

基于此,本文就以上述3個需求場景為例來介紹如何自定義 FeignClient 的配置

FeignClient的默認配置類

Feign Client 默認的配置類為 FeignClientsConfiguration, 這個類在 spring-cloud-netflix-core 的 jar 包下。

默認注入了很多 Feign 相關的配置Bean,包括FeignRetryer、 FeignLoggerFactory 和 FormattingConversionService 等。另外,Decoder、Encoder和 Contract 這3個類在沒有Bean被注入的情況下,會自動注入默認配置的 Bean,即ResponseEntity Decoder、SpringEncoder 和 SpringMvcContract。

如果你不知道如何自己定義配置時,不放點進去看看人家默認配置是如何實現(xiàn)的。這里就不曬源碼了。

FeignClient 注解參數(shù)

每個注解參數(shù)都做了注釋,詳情請見下方源碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {

	/**
	 * 指定FeignClient的名稱,如果項目使用了Ribbon,name屬性會作為微服務的名稱,用于服務發(fā)現(xiàn)
	 */
	@AliasFor("name")
	String value() default "";
	@Deprecated
	String serviceId() default "";
	@AliasFor("value")
	String name() default "";
	
	/**
	 * Sets the <code>@Qualifier</code> value for the feign client.
	 * 這個bean在應用上下文中的名字為接口的全限定名,你也可以使用 @FeignClient 注解中的 qualifier 屬性給bean指定一個別名
	 */
	String qualifier() default "";

	/**
	 * url地址
	 */
	String url() default "";

	/**
	 * 當發(fā)生404錯誤,如果該字段為true,會調(diào)用decoder進行解碼,否則拋出FeignException
	 */
	boolean decode404() default false;

	/**
	 * 指定FeignClient 的配置類,優(yōu)先級最高,默認的配置類為 FeignClientsConfiguration類
	 */
	Class<?>[] configuration() default {};

	/**
	 * 配置熔斷器的處理類
	 */
	Class<?> fallback() default void.class;

	/**
	 * 工廠類,用于生產(chǎn)fallback類示例,通過這個屬性我們可以實現(xiàn)每個接口通用的容錯邏輯,減少重復代碼
	 */
	Class<?> fallbackFactory() default void.class;

	/**
	 * 定義統(tǒng)一的路徑前綴
	 */
	String path() default "";

	/**
	 * Whether to mark the feign proxy as a primary bean. Defaults to true.
	 */
	boolean primary() default true;
}

自定義Feign配置類

在 Spring Cloud 中,你可以通過 @FeignClient 注解聲明額外的配置(比 FeignClientsConfiguration 級別高)去控制feign客戶端,以一開始的feign接口為例:

/**
 * @author axin
 * @suammry xx 客戶端
 */
@FeignClient(value = "xxClient",url = "${xx.host:www.axin.com}",configuration = MyConfiguration.class)
public interface DemoClient {

  @PostMapping(value = "/xxx/url", headers = "Content-Type=application/json"})
  yourResponse requestHTTP(@RequestBody JSONObject param);
}

在上面這個示例中,feign客戶端在MyConfiguration中的配置將會覆蓋FeignClientsConfiguration中的配置。

要注意的是: MyConfiguration不需要使用@Configuration注解。如果加上了,它將全局生效。

Retryer-重試機制的自定義

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
public class MyConfiguration {

  /**
   * 自定義重試機制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //fegin提供的默認實現(xiàn),最大請求次數(shù)為5,初始間隔時間為100ms,下次間隔時間1.5倍遞增,重試間最大間隔時間為1s,
    return new Retryer.Default();
  }
}

ErrorDecoder-錯誤解碼器的自定義

當feign調(diào)用返回HTTP報文時,會觸發(fā)這個方法,方法內(nèi)可以獲得HTTP狀態(tài)碼,可以用來定制一些處理邏輯等等。

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
@Slf4j
public class MyConfiguration {

  /**
   * 自定義重試機制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //最大請求次數(shù)為5,初始間隔時間為100ms,下次間隔時間1.5倍遞增,重試間最大間隔時間為1s,
    return new Retryer.Default();
  }

  @Bean
  public ErrorDecoder feignError() {
    return (key, response) -> {
      if (response.status() == 400) {
        log.error("請求xxx服務400參數(shù)錯誤,返回:{}", response.body());
      }

      if (response.status() == 409) {
        log.error("請求xxx服務409異常,返回:{}", response.body());
      }

      if (response.status() == 404) {
        log.error("請求xxx服務404異常,返回:{}", response.body());
      }

      // 其他異常交給Default去解碼處理
      // 這里使用單例即可,Default不用每次都去new
      return new ErrorDecoder.Default().decode(key, response);
    };
  }

}

采用了lambda的寫法,response變量是Response類型,通過status()方法可以拿到返回的HTTP狀態(tài)碼,body()可以獲得到響應報文。

Feign攔截器實踐

攔截器在請求發(fā)出之前執(zhí)行,在攔截器代碼里可以修改請求參數(shù),header等等,如果你有簽名生成的需求,可以放在攔截器中來實現(xiàn)

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
@Slf4j
public class MyConfiguration {

  /**
   * 自定義重試機制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //最大請求次數(shù)為5,初始間隔時間為100ms,下次間隔時間1.5倍遞增,重試間最大間隔時間為1s,
    return new Retryer.Default();
  }

  @Bean
  public ErrorDecoder feignError() {
    return (key, response) -> {
      if (response.status() == 400) {
        log.error("請求xxx服務400參數(shù)錯誤,返回:{}", response.body());
      }

      if (response.status() == 409) {
        log.error("請求xxx服務409異常,返回:{}", response.body());
      }

      if (response.status() == 404) {
        log.error("請求xxx服務404異常,返回:{}", response.body());
      }

      // 其他異常交給Default去解碼處理
      // 這里使用單例即可,Default不用每次都去new
      return new ErrorDecoder.Default().decode(key, response);
    };
  }

   /**
   * fegin 攔截器
   * @return
   */
  @Bean
  public RequestInterceptor cameraSign() {
    return template -> {

      // 如果是get請求
      if (template.method().equals(Request.HttpMethod.GET.name())) {
        //獲取到get請求的參數(shù)
        Map<String, Collection<String>> queries = template.queries();
      }

      //如果是Post請求
      if (template.method().equals(Request.HttpMethod.POST.name())) {
        //獲得請求body
        String body = template.requestBody().asString();
        JSONPObject request = JSON.parseObject(body, JSONPObject.class);
      }

      //Do what you want... 例如生成接口簽名

      String sign = "根據(jù)請求參數(shù)生成的簽名";
      //放入url?之后
      template.query("sign", sign);

      //放入請求body中
      String newBody = "原有body" + sign;
      template.body(Request.Body.encoded(newBody.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
    };
  }
}

可以看到代碼中給了如何獲取請求參數(shù)和修改請求參數(shù)的示例。

總結

小結一下,對于開頭提出的場景:

  1. 我想在發(fā)起請求響應超時失敗時自動重試 —— 自定義重試機制
  2. 我想單獨對某些異常的HTTP狀態(tài)碼特殊處理 —— 自定義ErrorDecoder
  3. 服務端接口需要驗證簽名,所以我方在發(fā)起請求時要生成簽名然后傳過去 —— 定義 Fegin 攔截器

給出了自定義 feign 配置的方式實現(xiàn)的樣例代碼,希望對你有用,如果有更好的方式簡化HTTP請求,歡迎留言分享~

參考鏈接

重新定義Spring Cloud實戰(zhàn)

Spring Cloud Netflix官方文檔

總結

到此這篇關于Spring Cloud Feign 自定義配置(重試、攔截與錯誤碼處理) 實踐的文章就介紹到這了,更多相關Spring Cloud Feign 自定義配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • IDEA 如何導入別人的javaweb項目進行部署

    IDEA 如何導入別人的javaweb項目進行部署

    這篇文章主要介紹了IDEA 如何導入別人的javaweb項目進行部署,本文給大家分享我的詳細部署過程及遇到問題解決方法,需要的朋友可以參考下
    2023-03-03
  • 老生常談java垃圾回收算法(必看篇)

    老生常談java垃圾回收算法(必看篇)

    下面小編就為大家?guī)硪黄仙U刯ava垃圾回收算法(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 關于mybatisPlus?yml配置方式

    關于mybatisPlus?yml配置方式

    這篇文章主要介紹了mybatisPlus?yml配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 為什么程序中突然多了 200 個 Dubbo-thread 線程的說明

    為什么程序中突然多了 200 個 Dubbo-thread 線程的說明

    這篇文章主要介紹了為什么程序中突然多了 200 個 Dubbo-thread 線程的說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java的Lombok之@Builder使用總結

    Java的Lombok之@Builder使用總結

    這篇文章主要介紹了Java的Lombok之@Builder使用總結,當不使用@Builder注解到類上,創(chuàng)建T1的有參構造函數(shù),入?yún)⒉粌H包括T1中所有的參數(shù),還包括T中所有的參數(shù),T2的屬性由T1在有參構造函數(shù)中通過調(diào)用父類構造器的方式賦初值,需要的朋友可以參考下
    2023-12-12
  • idea新建聚合項目并附上標簽的詳細過程

    idea新建聚合項目并附上標簽的詳細過程

    這篇文章主要介紹了idea新建聚合項目并附上標簽的詳細過程,本文通過實例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Springboot?前后端分離項目使用?POI?生成并導出?Excel的操作方法

    Springboot?前后端分離項目使用?POI?生成并導出?Excel的操作方法

    在做一個?SpringBoot?前后端分離項目的時候,需要將數(shù)據(jù)存到?Excel中,用戶可以下載?Excel,具體實現(xiàn)是采用?Apache?強大的?POI,本文給大家介紹Springboot?前后端分離項目使用?POI?生成并導出?Excel相關知識,感興趣的朋友一起看看吧
    2023-09-09
  • SpringBoot實現(xiàn)Server-Sent Events(SSE)的使用完整指南

    SpringBoot實現(xiàn)Server-Sent Events(SSE)的使用完整指南

    使用SpringBoot實現(xiàn)Server-Sent Events(SSE)可以有效處理實時數(shù)據(jù)推送需求,具有單向通信、輕量級和高實時性等優(yōu)勢,本文詳細介紹了在SpringBoot中創(chuàng)建SSE端點的步驟,并通過代碼示例展示了客戶端如何接收數(shù)據(jù),適用于實時通知、數(shù)據(jù)展示和在線聊天等場景
    2024-09-09
  • checkpoint 機制具體實現(xiàn)示例詳解

    checkpoint 機制具體實現(xiàn)示例詳解

    這篇文章主要為大家介紹了checkpoint 機制具體實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 淺談java實現(xiàn)mongoDB的多條件查詢

    淺談java實現(xiàn)mongoDB的多條件查詢

    這篇文章主要介紹了java實現(xiàn)mongoDB的多條件查詢,具有一定參考價值,需要的朋友可以參考下。
    2017-09-09

最新評論

曲阜市| 古交市| 永定县| 明光市| 巴彦淖尔市| 新巴尔虎左旗| 武冈市| 宁安市| 琼中| 武宣县| 措勤县| 泸州市| 炉霍县| 资溪县| 鸡泽县| 祥云县| 上栗县| 隆化县| 凤凰县| 新乡市| 荆门市| 福州市| 囊谦县| 嘉黎县| 蓬安县| 塔河县| 平陆县| 台中县| 藁城市| 南城县| 巴南区| 固镇县| 塔河县| 郯城县| 缙云县| 澜沧| 聂荣县| 怀安县| 嘉兴市| 会宁县| 宣恩县|