91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用原生的Feign

發布時間:2021-11-01 09:16:06 來源:億速云 閱讀:311 作者:小新 欄目:開發技術

這篇文章主要介紹了怎么使用原生的Feign,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

    什么是Feign

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

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

    怎么使用原生的Feign

    為什么使用Feign

    為什么要使用HTTP client

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

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

    怎么使用原生的Feign

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

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

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

    為什么要使用Feign

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

    如何使用Feign

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

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

    項目環境說明

    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 這個倉庫的所有貢獻者。

    通過下面的代碼可以發現,Feign 本質上是使用了動態代理來生成訪問 HTTP API 的代碼,定義 HTTP API 的過程有點像在定義 advice。

    // 定義HTTP API
    interface GitHub {
        
        @RequestLine("GET /repos/{owner}/{repo}/contributors")
        // @RequestLine(value = "GET /repos/{owner}/{repo}/contributors", decodeSlash = false)// 測試轉義"/"、"+"
        // @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()) // 返回內容為json格式,所以需要用到json解碼器
                    // .options(new Request.Options(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true)) // 配置超時參數等
                    .target(GitHub.class, "https://api.github.com");
    
            // 像調用方法一樣訪問HTTP API
            github.contributors("OpenFeign", "feign").stream()
                .map(contributor -> contributor.login + " (" + contributor.contributions + ")")
                .forEach(System.out::println);
        }
    }

    個性化配置

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

    怎么使用原生的Feign

    更換為Spring的注解

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

    怎么使用原生的Feign

    下面就是使用 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 照樣提供了支持。

    怎么使用原生的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");
        }
    }
    自定義內置的HTTP client

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

    怎么使用原生的Feign

    這里用 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,我們可以通過兩種方式實現:一是使用注解定義 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");
        }
    }
    自定義重試器

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

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

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

    public class MyRetryer implements Retryer {
        
        int attempt = 0;
    
        @Override
        public void continueOrPropagate(RetryableException e) {
            // 如果把RetryableException拋出,則不會繼續重試
            // 否則繼續重試
            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");
        }
    }

    感謝你能夠認真閱讀完這篇文章,希望小編分享的“怎么使用原生的Feign”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    开平市| 绍兴县| 闻喜县| 郎溪县| 宜都市| 山西省| 阿勒泰市| 河源市| 宣恩县| 晋城| 台前县| 南投县| 铜陵市| 甘谷县| 新昌县| 德州市| 浦县| 思茅市| 南宫市| 南丰县| 双桥区| 贡觉县| 遵义县| 宁明县| 三明市| 宁河县| 景宁| 报价| 城固县| 上思县| 砀山县| 和田县| 青神县| 甘南县| 治多县| 衡阳市| 中西区| 宿州市| 郁南县| 视频| 来安县|