开发者

SpringBoot Feign使用教程超全面讲解

开发者 https://www.devze.com 2022-11-29 10:38 出处:网络 作者: 程序一逸
目录开篇一、使用Feign的示例1.1添加依赖1.2启用Feign1.3编写FeignClient接口1.4编写对应的服务端1.5调用FeignClient二、如何切换Clie...
目录
  • 开篇
  • 一、使用 Feign 的示例
    • 1.1 添加依赖
    • 1.2 启用 Feign
    • 1.3 编写 FeignClient 接口
    • 1.4 编写对应的服务端
    • 1.5 调用 FeignClient
  • 二、如何切换 Client
    • 2.1 使用 Apache 的 HTTP Client
      • 2.1.1 添加依赖
      • 2.1.2 配置启用
    • 2.2 使用 OkHttp
      • 2.2.1 添加依赖
      • 2.2.2 配置启用
  • 三、如何修改日志级别
    • 3.1 通过配置文件修改日志级别
      • 3.2 通过配置类修改日志级别
      • 四、如何实现数据压缩
        • 五、FeignClienwww.devze.comt 的配置以及配置的优先级机制
          • 5.1 通过自定义配置类来定制配置
            • 5.2 在配置文件中设置全局配置
              • 5.3 在配置文件中设置专属配置
                • 5.4 理解配置的优先级与拦截器的追加原则
                  • 5.4.1 优先级的效果
                  • 5.4.2 追加的原则
                  • 5.4.3 拦截器的效果验证
              • 总结

                开篇

                Feign 是声明式、模板化的 HTTP 客户端, 可以帮助我们更快捷、优雅地调用 HTTP API;Spring Cloud 为 Feign 添加了 Spring MVC 的注解支持,并整合了 Ribbon 和 Eureka 来为使用 Feign 时提供负载均衡;在 Spring Cloud 中使用 Feign 是非常容易的。

                本篇主要介绍 SpringBoot 中要玩转 Feign 需要掌握的如添加 pom 依赖、客户端注解启用、切换底层 HttpClient、配置数据压缩、调整日志级别、定制配置、配置的优先级机制、增加拦截器以及拦截器的追加机制等知识。

                一、使用 Feign 的示例

                1.1 添加依赖

                <dependencies>
                  <!--openfein的依赖-->
                  开发者_Js入门<dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-starter-openfewww.devze.comign</artifactId>
                      <version>2.1.3.RELEASE</version>
                  </dependency>
                </dependencies>

                1.2 启用 Feign

                在 SpringBoot 的启用类上添加注解@EnableFeignClients@EnableFeignClients用于开启 Feign,会自动扫描@FeignClient标注的 FeignClient 接口。

                @SpringBootApplication
                @EnableFeignClients
                @EnableWeb
                public class FeignApplication {
                    public static void main(String[] args) {
                        SpringApplication.run(FeignApplication.class,args);
                    }
                }

                1.3 编写 FeignClient 接口

                @FeignClient(
                        name = "demo-service",
                        url = "http://localhost:8080/feign/server/",
                        configuration = FeignInterceptor.class,
                        fallback = TestService.DefaultFallback.class
                )
                public interface TestService {
                    @RequestMapping(value = "/getError/{id}", method = RequestMethod.GET)
                    public String getError(@RequestParam("id") Integer id);
                    @RequestMapping(value = "/get1", method = RequestMethod.GET)
                    public String get1();
                    @RequestMapping(value = "/get2/{param}", method = RequestMethod.GET)
                    public String get2(@RequestParam("param") String param);
                    @RequestMapping(value = "/post1", method = RequestMethod.POST)
                    public FeignDemo post1(@RequestBody FeignDemo demo);

                1.4 编写对应的服务端

                @RestController
                @RequestMapping("/feign/server")
                public class FeignServerController {
                    @GetMapping("/get1")
                    public String get1() {
                        return "get1";
                    }
                    @GetMapping("/get2/{para}")
                    public String get2(@PathVariable("para") String para){
                        return para;
                    }
                    @PostMapping("/post1")
                    public FeignDemo  post1(@RequestBody FeignDemo demo) {
                        return demo;
                    }
                }
                public class FeignDemo {
                    private String name;
                    private Integer age;
                    public String getName() {
                        return name;
                    }
                    public void setName(String name) {
                        this.name = name;
                    }
                    public Integer getAge() {
                        return age;
                    }
                    public void setAge(Integer age) {
                        this.age = age;
                    }
                    @Override
                    public String toString() {
                        return "FeignDemo{" +
                                "name='" + name + ''' +
                                ", age=" + age +
                                '}';
                    }
                }

                1.5 调用 FeignClient

                @RunWith(SpringJUnit4ClassRunner.class)
                @SpringBootTest(classes = {FeignApplication.class},webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
                @ActiveProfiles("dev,feign")
                public class FephpignClientTest {
                    @Autowired
                    private TestService testService;
                    @Test
                    public void testFallback(){
                        testService.getError(1);
                    }
                    @Test
                    public void testGet1(){
                        System.out.println(testService.get1());
                        System.out.println(testService.get2("abc"));
                        System.out.printf("..");
                        FeignDemo feignDemo = new FeignDemo();
                        feignDemo.setName("name");
                        feignDemo.setAge(1);
                        System.out.println(testService.post1(feignDemo));
                    }
                @Component
                    public class DefaultFallback implements TestService {
                        @Override
                        public String getError(@RequestParam("id") Integer id){
                            return "";
                        }
                        @Override
                        public String get1() {
                            returnjs null;
                        }
                        @Override
                        public String get2(String param) {
                            return null;
                        }
                        @Override
                        public FeignDemo post1(FeignDemo demo) {
                            return null;
                        }
                    }
                }

                二、如何切换 Client

                Feign 中自带的是 HttpURLConnection,这个 client 健壮性差,可替换为成熟的 Apache HttpClient 或 OkHttp 来进行网络请求。

                2.1 使用 Apache 的 HTTP Client

                使用 Apache 的httpclient替换 Feign 中默认的 client。

                2.1.1 添加依赖

                <!--httpclient的依赖,因为选择了使用httpclient-->
                <dependency>
                    <groupId>org.apache.httpcomponents</groupId>
                  php  <artifactId>httpclient</artifactId>
                </dependency>
                <dependency>
                    <groupId>io.github.openfeign</groupId>
                    <artifactId>feign-httpclient</artifactId>
                    <version>10.4.0</version>
                </dependency>
                

                2.1.2 配置启用

                配置中添加如下信息,表示启用httpclient

                feign:

                  httpclient:

                    enabled: true

                2.2 使用 OkHttp

                2.2.1 添加依赖

                在 Feign 中使用OkHttp作为网络请求框架,则只需要在 pom 文件中加上feign-okhttp的依赖,代码如下:

                <dependency>
                    <groupId>io.github.openfeign</groupId>
                    <artifactId>feign-okhttp</artifactId>
                    <version>10.2.0</version>
                </dependency>
                

                2.2.2 配置启用

                feign:

                  okhttp:

                    enabled: true

                三、如何修改日志级别

                在发送和接收请求的时候,其内部将日志的打印输出定义成了四个等级,对应的详情如下:

                级别说明
                NONE不做任何记录
                BASIC仅记录请求方法和 URL 以及响应状态代码和执行时间
                HEADERS记录基本信息以及请求和响应标头
                FULL记录请求和响应的标题,正文和元数据

                3.1 通过配置文件修改日志级别

                注意需要指定接口的全限定名

                logging:

                  level:

                    com.zto.titans.test.feign.service.TestService : DEBUG

                3.2 通过配置类修改日志级别

                @Configuration
                public class FooConfiguration {
                    @Bean
                    Logger.Level feignLoggerLevel() {
                        return Logger.Level.FULL;
                    }
                }
                

                这个一看即懂,不再废话。

                四、如何实现数据压缩

                可以分别对 HTTP 通信的requestresponse设置是否启用 GZIP 压缩,配置方法如下:

                feign:

                    compression:

                        request:

                            enabled: true

                            mime-types: text/XML,application/xml,application/json # 配置压缩支持的MIME TYPE

                            min-request-size: 2048  # 配置压缩数据大小的下限

                        response:

                            enabled: true # 配置响应GZIP压缩

                五、FeignClient 的配置以及配置的优先级机制

                有 2 种途径设置 FeignClient 的配置,通过自定义配置类来设置配置和在配置文件中设置,其中配置文件方式有点特殊,它里边可以指定全局配置对所有 FeignClient 有效,也可以为特定名称的 FeignClient 设置专属的配置。

                5.1 通过自定义配置类来定制配置

                实现一个配置类

                public class TestConfiguration {
                    @Bean
                    Logger.Level feignLoggerLevel() {
                        return Logger.Level.FULL;
                    }
                }
                

                将配置类TestConfiguration指定给configuration

                @FeignClient(
                        name = "test-service",
                        configuration = {FeignInterceptor2.class,TestConfiguration.class}
                )
                

                5.2 在配置文件中设置全局配置

                feign.client.config.default.xxx ,这个default意为全局的配置属性。

                feign:

                  client:

                    config:

                      default:

                        connectTimeout: 5000

                        readTimeout: 5000

                        loggerLevel: basic

                5.3 在配置文件中设置专属配置

                feign.client.config.feignName.xxx , 给名字为feignName的FeignClient指定专属的配置。

                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

                5.4 理解配置的优先级与拦截器的追加原则

                org.springframework.cloud.openfeign.FeignClientFactoryBean#configureFeign中可以确认以上 3 种配置的优先级:

                configureUsingConfiguration(context, builder); // 1
                configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()),builder); //2
                configureUsingProperties(properties.getConfig().get(this.contextId),builder);//3
                • 第 1 类为通过自定义配置类来指定配置
                • 第 2 类为在配置文件中的feign.client.config.default.xxx设置全局配置
                • 第 3 类为在配置文件中的feign.client.config.feignName.xxx设置专属配置

                5.4.1 优先级的效果

                配置文件里的专属配置-覆盖->配置文件里的全局配置-覆盖->配置类的配置

                5.4.2 追加的原则

                RequestInterceptor是拦截器,可以在发送前做一些处理,比如统一添加header信息。每一类中的requestInterceptors可以存储多个拦截器,拦截器并非覆盖的效果,而是链式追加的效果;从执行顺序来看优先级是:1 > 2 > 3,即先执行配置类中指定的拦截器,然后是配置文件中指定的全局拦截器,最后是配置文件中指定的专属拦截器。

                需特别注意:RequestInterceptor的实现类(例如 RI-A,RI-B)上如果添加了@Component注解,就都会被扫描识别到,并被追加到第一类的requestInterceptors列表中;倘若不小心 RI-A 还在第 2 类中又被指定了,则还会将拦截器 RI-A 追加在第二类的requestInterceptors列表中,结果是会 RI-A 总计会执行 2 次;若也在第三类中指定 RI-A,则 RI-A 也在其列表中追加,结果是 RI-A 总计会执行 3 次。

                5.4.3 拦截器的效果验证

                以一个实例来验证说明效果

                自定义三个 RequestInterceptor

                class FeignInterceptor implements RequestInterceptor {
                    @Override
                    public void apply(RequestTemplate requestTemplate) {
                        requestTemplate.header("user", "myuser1");
                        requestTemplate.header("password", "mypassword");
                    }
                }
                
                class FeignInterceptor1 implements RequestInterceptor {
                    @Override
                    public void apply(RequestTemplate requestTemplate) {
                        requestTemplate.header("user1", "myuser1");
                        requestTemplate.header("password1", "mypassword1");
                    }
                }
                
                class FeignInterceptor2 implements RequestInterceptor {
                    @Override
                    public void apply(RequestTemplate requestTemplate) {
                        requestTemplate.header("user2", "myuser2");
                        requestTemplate.header("password2", "mypassword2");
                    }
                }
                

                @FeignClient 中指定一个

                @FeignClient(
                        name = "test-service",
                        url = "http://localhost:8080/feign/server/",
                        configuration = {FeignInterceptor.class,TestConfiguration.class},
                        fallback = TestService.DefaultFallback.class
                )
                

                配置中指定 2 个

                default指定了一个,test-service里指定一个

                feign:

                  httpclient:

                    enabled: true

                  okhttp:

                    enabled: true

                  client:

                    config:

                      default:

                        connectTimeout: 5000

                        readTimeout: 5000

                        #loggerLevel: none

                        requestInterceptors:

                          - com.zto.titans.test.feign.service.FeignInterceptor1

                      test-service:

                        #loggerLevel: basic

                        requestInterceptors:

                          - com.zto.titans.test.feign.service.FeignInterceptor2

                logging:

                  level:

                    com.zto.titans.test.feign.service.TestService : DEBUG

                根据追加逻辑,最终执行的顺序是:

                • FeignInterceptor
                • FeignInterceptor1
                • FeignInterceptor2

                总结

                本篇主要介绍 SpringBoot 中要玩转 Feign 需要掌握的如添加 pom 依赖、客户端注解启用、切换底层 HttpClient、配置数据压缩、调整日志级别、定制配置、配置的优先级机制、增加拦截器以及拦截器的追加机制等知识,以实例 + 效果的方式帮读者高效全面并深入的理解它们。

                到此这篇关于SpringBoot Feign使用教程超全面讲解的文章就介绍到这了,更多相关SpringBoot Feign内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

                0

                精彩评论

                暂无评论...
                验证码 换一张
                取 消

                关注公众号