Spring Cloud Feign(声明式/模板化的HTTP客户端)

简介: 来源Feign使得 Java HTTP 客户端编写更方便。Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket。Feign 最初是为了降低统一绑定Denominator到 HTTP API 的复杂度,不区分是否支持 Restful。

来源

Feign使得 Java HTTP 客户端编写更方便。Feign 灵感来源于RetrofitJAXRS-2.0WebSocketFeign 最初是为了降低统一绑定DenominatorHTTP API 的复杂度,不区分是否支持 Restful

Retrofit是Square开发的一个AndroidJavaREST客户端库。
github地址:https://github.com/square/retrofit

JAX-RS(Java API for RESTful Web Services) 2.0 又称JSR 339 不仅定义了一套用于构建 RESTful 网络服务的 API,同时也通过增强客户端 API 功能简化了REST 客户端的构建过程。
github地址:https://github.com/eclipse-ee4j/jaxrs-api
WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。
协议说明:https://tools.ietf.org/html/rfc6455

Denominator是一个用于操作DNS云的可移植Java
github地址:https://github.com/Netflix/Denominator

简介

Spring Cloud Netflix 的微服务都是以 HTTP 接口的形式暴露的,
所以调用方式有:
JDK原生的URLConnection
Apache的Http Client
Netty的异步HTTP Client
Spring的RestTemplate
Feign
而 Feign 是一个使用起来更加方便的 HTTP 客戶端,使用起来就像是调用自身工程的方法,而感觉不到是调用远程方法。feign还支持可插拔的编码器和解码器,Spring在用的时候增加了对@requestMapping的处理,Feign 的目的是尽量的减少资源和代码来实现和HTTP API的连接。通过自定义的编码解码器以及错误处理,可以编写任何基于文本的HTTP API

github地址:https://github.com/OpenFeign/feign
在源码中可以看到子模块包括RibbonHystrix,所以feign是基于RibbonHystrix的声明式服务调用组件。Feign是一种声明式、模板化的HTTP客户端。

`

实现声明式REST客户端Feign

引入Spring Cloud Feign依赖以及相关依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

注:网上有的文章说引入的依赖是spring-cloud-starter-feign,其实官方不再推荐使用,推荐使用spring-cloud-starter-openfeign

在应用主类中通过@EnableFeignClients注解开启Feign功能,因为要注册服务,所以还要使用@EnableEurekaClient

@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
public class SpringcloudFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudFeignApplication.class, args);
    }
}

修改yml配置文件

server:
  port: 8088
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka
spring:
  application:
    name: springcloud-feign-client

重点:Feign声明式/模块化体现

接下来定义服务接口类
使用@FeignClient("springcloud-eureka-client")注解来绑定该接口对应springcloud-eureka-client服务

@Component
@FeignClient(name = "springcloud-eureka-client")
public interface Client {
    @GetMapping("/client")
    public String getInfo();
}

通过声明式的注解,提供一个供其它服务调用的 Client。
@FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入
注:多个feignCLient类中@FeignClient注解中的name值不能重复,url可以重复
Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。

注意:绑定的接口服务必须是对应服务上存在的接口
例如我把接口名改为client123便会报如下错误

image.png

也就是找不到对应的接口服务,所绑定的springcloud-eureka-client没有client123接口

这是springcloud-eureka-client服务中的client接口

@RestController
public class DiscoveryController {
    @Autowired
    private DiscoveryClient discoveryClient;
    @Value("${server.port}")
    private String ip;

    @GetMapping("/client")
    public String client() {
        String services = "调用的服务是: " + discoveryClient.getServices()+" 对应的端口号 :"+ip;
        System.out.println("调用的服务是: " + discoveryClient.getServices()+" 对应的端口号 :"+ip);
        return services;
    }
}

调用上面定义的接口

@RestController
public class FeignClientController {
    @Autowired
    Client client;
    @GetMapping("/info")
    public String getInfo(){
        return client.getInfo();
    };
}

这里的接口名就任意取了,这里主要是获取绑定服务的接口的信息。

整体项目结构

Eureka服务端 端口号是9090
Eureka客户端 端口号是8082 服务名springcloud-eureka-client
feign消费者客户端 端口号是8088
(如需测试负载均衡的可以再启动一个端口号为8081的服务,服务名同样是springcloud-eureka-client)

启动服务进行测试

先启动服务端再启动客户端,客户端启动顺序没要求
访问http://localhost:9090服务注册中心

image.png

在服务注册中心可以看到,服务提供者和消费者都注册好了

访问feign定义的接口/infohttp://localhost:8088/info

image.png

测试负载均衡

服务列表

image.png

访问http://localhost:8088/info
image.png

刷新下,再次访问
image.png

实现了与Ribbon相同的负载均衡功能

实现Feign熔断

需要先写一个调用延迟或失败时调用的类

@Component
public class FailClass implements Client{
    @Override
    public String getInfo() {
        return "服务中断连接,请联系管理员";
    }
}

需要实现自定义服务接口的方法,以至于显示对应服务的对应接口调用失败的返回信息
然后在自定义服务接口中添加fallback异常处理回调。

@Component
@FeignClient(name = "springcloud-eureka-client",fallback = FailClass.class)
public interface Client {
    @GetMapping("/client")
    public String getInfo();
}

还需要在yml配置文件中开启熔断,默认为false

feign:
  hystrix:
    enabled: true

关闭两个springcloud-eureka-client服务后访问http://localhost:8088/info会显示

image.png

总结:

其实通过Feign封装了HTTP调用服务方法,使得客户端像调用本地方法那样直接调用方法,Feign本质上是个HTTP客户端
Feign继承特性用起来确实很方便,但是也带来一个问题,就是服务提供者和服务消费者的耦合度太高,此时如果服务提供者修改了一个接口的定义,服务消费者可能也得跟着变化,进而带来很多未知的工作量,如果通过此方法来实现接口共享的话,建议严格遵守面向对象的开闭原则,尽可能低做好前后版本兼容,防止因为版本原因造成接口定义的不一致。

推荐文章
Feign相关参数配置:https://blog.csdn.net/u012702547/article/details/78327668?locationNum=10&fps=1
Feign源码分析:https://blog.csdn.net/forezp/article/details/73480304

目录
相关文章
|
2月前
|
Java 数据库连接 数据库
spring复习05,spring整合mybatis,声明式事务
这篇文章详细介绍了如何在Spring框架中整合MyBatis以及如何配置声明式事务。主要内容包括:在Maven项目中添加依赖、创建实体类和Mapper接口、配置MyBatis核心配置文件和映射文件、配置数据源、创建sqlSessionFactory和sqlSessionTemplate、实现Mapper接口、配置声明式事务以及测试使用。此外,还解释了声明式事务的传播行为、隔离级别、只读提示和事务超时期间等概念。
spring复习05,spring整合mybatis,声明式事务
|
2月前
|
Java API 开发者
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
388 0
|
3月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
5月前
|
Java 应用服务中间件 微服务
spring boot 中Feign调用提示Request header is too large 解决方案
spring boot 中Feign调用提示Request header is too large 解决方案
223 1
|
4月前
|
XML Java 关系型数据库
面试一口气说出Spring的声明式事务@Transactional注解的6种失效场景
面试一口气说出Spring的声明式事务@Transactional注解的6种失效场景
119 0
|
5月前
|
XML Java 数据库
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
30 0
|
5月前
|
Java API Spring
Spring Boot中使用Feign进行HTTP请求
Spring Boot中使用Feign进行HTTP请求
|
JavaScript Java 测试技术
spring客户端使用
spring客户端使用
129 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
162 2

热门文章

最新文章