SpringCloud中的Feign详解

 更新时间:2023年09月11日 11:42:49   作者:silmeweed  
这篇文章主要介绍了SpringCloud中的Feign详解,Feign是一个声明式的Web Service客户端,以Java接口注解的方式调用Http请求,同时Feign整合了Ribbon和Hystrix,实现负载均衡与容断功能,需要的朋友可以参考下

一、简介:

Feign是一个声明式的Web Service客户端,以Java接口注解的方式调用Http请求。同时Feign整合了Ribbon和Hystrix,实现负载均衡与容断功能。

1. Feign具有如下特性:

  • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
  • 支持可插拔的HTTP编码器和解码器;
  • 支持Hystrix和它的Fallback;
  • 支持Ribbon的负载均衡;
  • 支持HTTP请求和响应的压缩
  • feign不支持GET请求直接传递POJO对象的.

2.@FeignClient注解说明

@FeignClient:是Spring识别OpenFeign客户端的注释,OpenFign客户端必须是接口。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {
    //1.Ribbon负载均衡器的Feign客户端的名称
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";
    //不使用ribbon时,请求url
    String url() default "";
    //配置响应状态码为404时是否应该抛出FeignExceptions
    boolean decode404() default false;
    //用于记录,拦截器等额外配置.
    Class<?>[] configuration() default {};
    //如果启用了Hystrix,则可以实现回退方法
    Class<?> fallback() default void.class;
    Class<?> fallbackFactory() default void.class;
    //自动给所有方法的requestMapping前加上前缀
    String path() default "";
    boolean primary() default true;
}

@FeignClient(value = "common-wx", url = "www.baidu.com/common-wx")

  • value/name:是将用于创建Ribbon负载均衡器的Feign客户端的名称.
  • url: 当您不使用Ribbon时,您还可以使用url属性将客户端指向目标应用程序。
  • fallback:如果启用了Hystrix,则可以实现回退方法.(底层依赖hystrix,启动类要加上@EnableHystrix)
  • configuration:用于记录,拦截器等额外配置.
  • path: 自动给所有方法的requestMapping前加上前缀,类似与controller类上的requestMapping
  • decode404:配置响应状态码为404时是否应该抛出FeignExceptions。(默认false)

3. HTTP客户端

OpenFeign的默认HTTP客户端HttpUrlConnection用于执行其HTTP请求。您可以配置其他客户端(ApacheHttpClient,OkHttpClient)

(1)使用OKhttp发送request

Feign底层默认是使用jdk中的HttpURLConnection发送HTTP请求,feign也提供了OKhttp来发送请求,具体配置如下:

//作用在所有Feign Client上的配置.
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic
  okhttp:
    enabled: true
  hystrix:
    enabled: true

4.构建器(启用feign客户端)

构建器是让我们创建一个客户端bean并返回一个Feign构建器。生成方式有二种:

(1) 基于面向接口的动态代理方式生成实现类。使用Feign.builder()操作类实现。 

(2) 使用注解@EnableFeignClients启用feign客户端.(需要结合使用注解@FeignClient 定义一起使用)

注解@EnableFeignClients:扫描和注册feign客户端bean定义。 注解@EnableFeignClients用于告诉框架扫描所有通过注解@FeignClient定义的feign客户端。

//1.生成Bean 
@Bean
AuthClient authClient() {
    return Feign.builder()
            .client(new ApacheHttpClient())//重新使用HttpClient
            .target(AuthClient.class, baseServerUrl);
}
//2.注解方式生成Bean(需要使用注解@FeignClient 定义结合)
@EnableFeignClients(
    defaultConfiguration = DefaultFeignConfiguration.class,
    basePackages= {"com.missuteam.onepiece.oauth.api.impl"}
)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
   //扫描的包路径
    String[] value() default {};
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
    //配置
    Class<?>[] defaultConfiguration() default {};
    //配置HttpClient 
    Class<?>[] clients() default {};
}
//自定义配置
@Configuration
public class DefaultFeignConfiguration {
    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(1000,3000,3);
    }
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.BASIC;
    }
}
//可配置的属性
public static class FeignClientConfiguration {
    private Logger.Level loggerLevel;
    private Integer connectTimeout;
    private Integer readTimeout;
    private Class<Retryer> retryer;
    private Class<ErrorDecoder> errorDecoder;
    private List<Class<RequestInterceptor>> requestInterceptors;
    private Boolean decode404;
    private Class<Decoder> decoder;
    private Class<Encoder> encoder;
    private Class<Contract> contract;
}

5. Contract协议规则(接口定义时的注释规则)

(1)默认Contract 实现:

Feign 默认有一套自己的协议规范,规定了一些注解,可以映射成对应的Http请求。

注解接口Target使用说明
@RequestLine方法上定义HttpMethod 和 UriTemplate. UriTemplate 中使用{} 包裹的表达式
@Param方法参数定义模板变量,模板变量的值可以使用名称的方式使用模板注入解析
@Headers类上或者方法上定义头部模板变量,使用@Param 注解提供参数值的注入。如果该注解添加在接口类上,则所有的请求都会携带对应的Header信息;如果在方法上,则只会添加到对应的方法请求上
@QueryMap方法上定义一个键值对或者 pojo,参数值将会被转换成URL上的 query 字符串上
@HeaderMap方法上定义一个HeaderMap, 与 UrlTemplate 和HeaderTemplate 类型,可以使用@Param 注解提供参数值

(2)基于Spring MVC的协议规范SpringMvcContract:

当前Spring Cloud 微服务解决方案中,为了降低学习成本,采用了Spring MVC的部分注解来完成 请求协议解析,也就是说 ,写客户端请求接口和像写服务端代码一样。目前的Spring MVC的注解并不是可以完全使用的,有一些注解并不支持,如 @GetMapping , @PutMapping  等,仅支持使用 @RequestMapping  等。

6.Feign开启GZIP压缩

Spring Cloud Feign支持对请求和响应进行GZIP压缩,以提高通信效率。开启GZIP压缩之后,Feign之间的调用数据通过二进制协议进行传输,返回值需要修改为ResponseEntity<byte[]>才可以正常显示。

//作用在所有Feign Client上的配置
feign:
  compression:
    request: #请求
      enabled: true #开启
      mime-types: text/xml,application/xml,application/json #开启支持压缩的MIME TYPE
      min-request-size: 2048 #配置压缩数据大小的下限
    response: #响应
      enabled: true #开启响应GZIP压缩

7. 配置:

##################FeignClientProperties###############
#全局默认配置名称:defalut
feign.client.config.defalut.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.defalut.connectTimeout=5000
#修改全局默认配置名称为:my-config
feign.client.default-config=my-config
feign.client.config.my-config.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.my-config.connectTimeout=5000
#局部配置,@FeignClient#name=user
feign.client.config.user.error-decoder=com.example.feign.MyErrorDecoder
feign.client.config.user.connectTimeout=5000
##################FeignHttpClientProperties##################
feign.httpclient.enabled=true
feign.httpclient.connectionTimeout=5000
##################FeignClientEncodingProperties##################
# 配置请求GZIP压缩
feign.compression.request.enabled=true
# 配置响应GZIP压缩 FeignContentGzipEncodingAutoConfiguration
feign.compression.response.enabled=true
# 配置压缩支持的MIME TYPE
feign.compression.request.mime-types=text/xml,application/xml,application/json
# 配置压缩数据大小的下限
feign.compression.request.min-request-size=2048

二、原理分析

在服务调用的场景中,我们经常调用基于Http协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等等。(如下图)

 在Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类,基本原理如下所示

到此这篇关于SpringCloud中的Feign详解的文章就介绍到这了,更多相关Feign详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis解决<foreach>标签不能超过1000的问题

    mybatis解决<foreach>标签不能超过1000的问题

    MyBatis是一个开源的持久层框架,它可以帮助开发者简化数据库操作的编写,而foreach是MyBatis中的一个重要标签,用于在SQL语句中进行循环操作,本文主要给大家介绍了mybatis解决<foreach>标签不能超过1000的问题,需要的朋友可以参考下
    2024-05-05
  • Docker报错pass store is uninitialized修复实现方式

    Docker报错pass store is uninitialized修复实现方式

    文章介绍了如何在Linux系统上使用docker-credential-pass进行Docker凭证管理的步骤,包括下载、安装依赖、生成GPG密钥、配置pass和docker-credential-pass,以及最终进行Docker登录
    2026-02-02
  • Java的JNI快速入门教程(推荐)

    Java的JNI快速入门教程(推荐)

    下面小编就为大家带来一篇Java的JNI快速入门教程(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • JavaSE反射与动态代理详细代码示例

    JavaSE反射与动态代理详细代码示例

    Java反射和动态代理是Java中两个强大的特性,它们允许程序在运行时动态地获取和操作类、方法、字段等信息,以及创建代理对象来实现AOP等功能,这篇文章主要介绍了JavaSE反射与动态代理的相关资料,需要的朋友可以参考下
    2026-04-04
  • Spring Cloud Config 使用本地配置文件方式

    Spring Cloud Config 使用本地配置文件方式

    这篇文章主要介绍了Spring Cloud Config 使用本地配置文件方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • mybatis trim标签的使用详解

    mybatis trim标签的使用详解

    这篇文章主要介绍了mybatis trim标签的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Spring的IOC代码解析

    Spring的IOC代码解析

    这篇文章主要介绍了Spring的IOC代码解析,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • 在Spring Boot中加载初始化数据的实现

    在Spring Boot中加载初始化数据的实现

    这篇文章主要介绍了在Spring Boot中加载初始化数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • SpringBoot+MyBatis-Plus+Velocity实现代码自动生成

    SpringBoot+MyBatis-Plus+Velocity实现代码自动生成

    本文主要介绍了使用SpringBoot、MyBatis-Plus和Velocity模板引擎实现代码自动生成器,该生成器能够根据数据库表结构自动生成增删改查操作的代码,感兴趣的可以了解一下
    2025-03-03
  • scala 操作数据库的方法

    scala 操作数据库的方法

    这篇文章主要介绍了scala 操作数据库的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06

最新评论