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

一文教你如何使用原生的Feign

 更新時間:2021年10月30日 12:20:49   作者:子月生  
Feign使得 Java HTTP 客戶端編寫更方便,Feign 靈感來源于Retrofit、JAXRS-2.0和WebSocket,這篇文章主要給大家介紹了如何使用原生的Feign的相關資料,需要的朋友可以參考下

什么是Feign

Feign 是由 Netflix 團隊開發(fā)的一款基于 Java 實現(xiàn)的 HTTP client,借鑒了 Retrofit、 JAXRS-2.0、WebSocket 等類庫。通過 Feign,我們可以像調(diào)用方法一樣非常簡單地訪問 HTTP API。這篇博客將介紹如何使用原生的 Feign,注意,是原生的,不是經(jīng)過 Spring 層層封裝的 Feign。

補充一下,在 maven 倉庫中搜索 feign,我們會看到兩種 Feign: OpenFeign Feign 和 Netflix Feign。它們有什么區(qū)別呢?簡單地說,OpenFeign Feign 的前身就是 Netflix Feign,因為 Netflix Feign 從 2016 年開始就不維護了,所以建議還是使用 OpenFeign Feign。

為什么使用Feign

為什么要使用HTTP client

首先,因為 Feign 本身是一款 HTTP client,所以,這里先回答:為什么使用 HTTP client?

假設不用 HTTP client,我們訪問 HTTP API 的過程大致如下。是不是相當復雜呢?直接操作 socket 已經(jīng)非常麻煩了,我們還必須在熟知 HTTP 協(xié)議的前提下自行完成報文的組裝和解析,代碼的復雜程度可想而知。

那么,這個過程是不是可以更簡單一些呢?

我們可以發(fā)現(xiàn),在上面的圖中,紅框的部分是相對通用的,是不是可以把這些邏輯封裝起來?基于這樣的思考,于是就有了 HTTP client(根據(jù)類庫的不同,封裝的層次會有差異)。

所以,為什么要使用 HTTP client 呢?簡單地說,就是為了讓我們更方便地訪問 HTTP API。

為什么要使用Feign

HTTP client 的類庫還有很多,例如 Retrofit、JDK 自帶的 HttpURLConnection、Apache HttpClient、OkHttp、Spring 的 RestTemplate,等等。我很少推薦說要使用哪種具體的類庫,如果真的要推薦 Feign 的話,主要是由于它優(yōu)秀的擴展性(不是一般的優(yōu)秀,后面的使用例子就可以看到)。

如何使用Feign

關于如何使用 Feign,官方給出了非常詳細的文檔,在我看過的第三方類庫中,算是比較少見的。

本文用到的例子也是參考了官方文檔。

項目環(huán)境說明

os:win 10

jdk:1.8.0_231

maven:3.6.3

IDE:Spring Tool Suite 4.6.1.RELEASE

引入依賴

這里引入 gson,是因為入門例子需要有一個 json 解碼器。

    <properties>
        <feign.version>11.2</feign.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>${feign.version}</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-gson</artifactId>
            <version>${feign.version}</version>
        </dependency>
    </dependencies>

入門例子

入門例子中使用 Feign 來訪問 github 的接口獲取 Feign 這個倉庫的所有貢獻者。

通過下面的代碼可以發(fā)現(xiàn),F(xiàn)eign 本質(zhì)上是使用了動態(tài)代理來生成訪問 HTTP API 的代碼,定義 HTTP API 的過程有點像在定義 advice。

// 定義HTTP API
interface GitHub {
    
    @RequestLine("GET /repos/{owner}/{repo}/contributors")
    // @RequestLine(value = "GET /repos/{owner}/{repo}/contributors", decodeSlash = false)// 測試轉(zhuǎn)義"/"、"+"
    // @RequestLine("GET /repos/{owner:[a-zA-Z]*}/{repo}/contributors")// 測試正則校驗
    // @Headers("Accept: application/json") // 測試添加header
    List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

public static class Contributor {
    String login;
    int contributions;
}

public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new GsonDecoder()) // 返回內(nèi)容為json格式,所以需要用到json解碼器
                // .options(new Request.Options(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true)) // 配置超時參數(shù)等
                .target(GitHub.class, "https://api.github.com");

        // 像調(diào)用方法一樣訪問HTTP API
        github.contributors("OpenFeign", "feign").stream()
            .map(contributor -> contributor.login + " (" + contributor.contributions + ")")
            .forEach(System.out::println);
    }
}

個性化配置

除了簡單方便之外,F(xiàn)eign 還有一個很大的亮點,就是有相當優(yōu)秀的擴展性,幾乎什么都可以自定義。下面是官方給的一張圖,基本涵蓋了 Feign 可以擴展的內(nèi)容。每個擴展支持都有一個對應的適配包,例如,更換解碼器為 jackson 時,需要引入io.github.openfeign:feign-jackson的適配包。

更換為Spring的注解

在入門例子中,我們使用 Feign 自帶的注解來定義 HTTP API。但是,對于習慣了 Spring 注解的許多人來說,無疑需要增加學習成本。我們自然會問,F(xiàn)eign 能不能支持 Spring 注解呢?答案是肯定的。Feign 不但能支持 Spring 注解,還可以支持 JAX-RS、SOAP 等等。

下面就是使用 Sping 注解定義 HTTP API 的例子。注意,pom 文件中要引入 io.github.openfeign:feign-spring4 的依賴。

// 定義HTTP API
interface GitHub {
    
    @GetMapping("/repos/{owner}/{repo}/contributors")
    List<Contributor> contributors(@RequestParam("owner") String owner, @RequestParam("repo") String repo);
}


public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new GsonDecoder())
                .contract(new SpringContract())// 自定義contract
                .target(GitHub.class, "https://api.github.com");
    }
}

自定義解碼器和編碼器

在入門例子中,我們使用 gson 來解析 json。那么,如果我想把它換成 jackson 行不行?Feign 照樣提供了支持。

注意,pom 文件中要引入 io.github.openfeign:feign-jackson 的依賴。

public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new JacksonDecoder()) // 自定義解碼器
                .encoder(new JacksonEncoder()) // 自定義編碼器
                .target(GitHub.class, "https://api.github.com");
    }
}

自定義內(nèi)置的HTTP client

接下來的這個自定義就更厲害了。Feign 本身作為一款 HTTP client,竟然還可以支持其他 HTTP client。

這里用 OkHttp 作例子。注意,pom 文件中要引入 io.github.openfeign:feign-okhttp 的依賴。

public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new GsonDecoder())
                .client(new OkHttpClient())// 自定義client
                .target(GitHub.class, "https://api.github.com");
    }
}

自定義攔截器

我們訪問外部接口時,有時需要帶上一些特定的 header,例如,應用標識、token,我們可以通過兩種方式實現(xiàn):一是使用注解定義 HTTP API,二是使用攔截器(更常用)。下面的例子中,使用攔截器給請求添加 token 請求頭。

public class MyInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("token", LoginUtils.getCurrentToken());
    }
}
public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new GsonDecoder())
                .requestInterceptor(new MyInterceptor())
                .target(GitHub.class, "https://api.github.com");
    }
}

自定義重試器

默認情況下,F(xiàn)eign 訪問 HTTP API 時,如果拋出IOException,它會認為是短暫的網(wǎng)絡異常而發(fā)起重試,這時,F(xiàn)eign 會使用默認的重試器feign.Retryer.Default(最多重試 5 次),如果不想啟用重試,則可以選擇另一個重試器feign.Retryer.NEVER_RETRY。當然,我們也可以自定義。

奇怪的是,F(xiàn)eign 通過重試器的 continueOrPropagate(RetryableException e)方法是否拋出RetryableException來判斷是否執(zhí)行重試,為什么不使用 true 或 false 來判斷呢?

注意,重試器是用來判斷是否執(zhí)行重試,自身不包含重試的邏輯。

public class MyRetryer implements Retryer {
    
    int attempt = 0;

    @Override
    public void continueOrPropagate(RetryableException e) {
        // 如果把RetryableException拋出,則不會繼續(xù)重試
        // 否則繼續(xù)重試
        if(attempt++ >= 3) {// 重試三次
            throw e;
        }
    }

    @Override
    public Retryer clone() {
        return this;
    }
}
public class MyApp {

    public static void main(String... args) {
        // 獲取用來訪問HTTP API的代理類
        GitHub github = Feign.builder()
                .decoder(new GsonDecoder())
                .retryer(new MyRetryer())
                //.retryer(Retryer.NEVER_RETRY) // 不重試
                .exceptionPropagationPolicy(ExceptionPropagationPolicy.UNWRAP)
                .target(GitHub.class, "https://api.github.com");
    }
}

結(jié)語

以上,基本講完 Feign 的使用方法,其實 Feign 還有其他可以擴展的東西,例如,斷路器、監(jiān)控等等。感興趣的話,可以自行分析。

到此這篇關于如何使用原生的Feign的文章就介紹到這了,更多相關使用原生的Feign內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

參考資料

Feign github

相關源碼請移步:https://github.com/ZhangZiSheng001/feign-demo

相關文章

  • springboot 多環(huán)境切換的方法

    springboot 多環(huán)境切換的方法

    這篇文章主要介紹了springboot 多環(huán)境切換的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • SpringBoot中HttpSessionListener的簡單使用方式

    SpringBoot中HttpSessionListener的簡單使用方式

    這篇文章主要介紹了SpringBoot中HttpSessionListener的簡單使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 解析Java線程編程中的線程安全與synchronized的使用

    解析Java線程編程中的線程安全與synchronized的使用

    這篇文章主要介紹了Java線程編程中的線程安全與synchronized的使用,synchronized多線程使用時一定要注意線程之間的沖突問題,需要的朋友可以參考下
    2015-12-12
  • Java中的WeakHashMap源碼分析

    Java中的WeakHashMap源碼分析

    這篇文章主要介紹了Java中的WeakHashMap源碼分析,WeakHashMap可能平時使用的頻率并不高,但是你可能聽過WeakHashMap會進行自動回收吧,下面就對其原理進行分析,需要的朋友可以參考下
    2023-09-09
  • Java中Arraylist的最大長度

    Java中Arraylist的最大長度

    這篇文章主要介紹了Java中Arraylist的最大長度,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java String[]字符串數(shù)組自動排序的簡單實現(xiàn)

    java String[]字符串數(shù)組自動排序的簡單實現(xiàn)

    下面小編就為大家?guī)硪黄猨ava String[]字符串數(shù)組自動排序的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • Java封裝數(shù)組之動態(tài)數(shù)組實現(xiàn)方法詳解

    Java封裝數(shù)組之動態(tài)數(shù)組實現(xiàn)方法詳解

    這篇文章主要介紹了Java封裝數(shù)組之動態(tài)數(shù)組實現(xiàn)方法,結(jié)合實例形式詳細分析了java動態(tài)數(shù)組的實現(xiàn)原理、操作步驟與相關注意事項,需要的朋友可以參考下
    2020-03-03
  • spring boot啟動時mybatis報循環(huán)依賴的錯誤(推薦)

    spring boot啟動時mybatis報循環(huán)依賴的錯誤(推薦)

    今天小編抽時間給大家分享spring boot啟動時mybatis報循環(huán)依賴的錯誤,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-12-12
  • java編程abstract類和方法詳解

    java編程abstract類和方法詳解

    這篇文章主要介紹了java編程abstract類和方法詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • 了解Maven的<relativePath/>標簽用法

    了解Maven的<relativePath/>標簽用法

    這篇文章主要介紹了了解Maven的<relativePath/>標簽用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

潼关县| 甘孜| 共和县| 垣曲县| 利辛县| 城口县| 沁源县| 乳源| 保定市| 苍山县| 长武县| 曲水县| 京山县| 漯河市| 江源县| 滦南县| 绿春县| 彰武县| 吴堡县| 蛟河市| 留坝县| 高淳县| 轮台县| 宽城| 宝坻区| 滨海县| 普安县| 伊通| 高平市| 鄢陵县| 桃源县| 武胜县| 灵山县| 禄丰县| 永胜县| 德庆县| 尉氏县| 常州市| 涟水县| 康乐县| 永平县|