优雅实现远程调⽤-OpenFeign

1. RestTemplate存在问题

 之前的代码:

虽说RestTemplate 对HTTP封装后, 已经⽐直接使⽤HTTPClient简单⽅便很多, 但是还存在⼀些问题.

1. 需要拼接URL, 灵活性⾼, 但是封装臃肿, URL复杂时, 容易出错.

2. 代码可读性差, ⻛格不统⼀.

微服务之间的通信⽅式, 通常有两种: RPC 和 HTTP.

在SpringCloud中, 默认是使⽤HTTP来进⾏微服务的通信, 最常⽤的实现形式有两种:

  • RestTemplate
  • OpenFeign

RPC(Remote Procedure Call)远程过程调⽤,是⼀种通过⽹络从远程计算机上请求服务,⽽不需要了解底层⽹络通信细节。

RPC可以使⽤多种⽹络协议进⾏通信, 如HTTP、TCP、UDP等, 并且在 TCP/IP⽹络四层模型中跨越了传输层和应⽤层。简⾔之RPC就是像调⽤本地⽅法⼀样调⽤远程⽅法。 常⻅的RPC框架有Dubbo,Thrift,gRPC

2. OpenFeign介绍

OpenFeign 是⼀个声明式的 Web Service 客⼾端. 它让微服务之间的调⽤变得更简单, 类似controller 调⽤service, 只需要创建⼀个接⼝,然后添加注解即可使⽤OpenFeign.

Spring Cloud Feign

Spring Cloud Feign 是 Spring 对 Feign 的封装, 将 Feign 项⽬集成到 Spring Cloud ⽣态系统中.

受 Feign 更名影响,Spring Cloud Feign 也有两个 starter:

  • spring-cloud-starter-feign
  • spring-cloud-starter-openfeign

由于Feign的停更维护, 对应的, 我们使⽤的依赖是 spring-cloud-starter-openfeign

3. 使用

3.1 依赖

 

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

3.2 注解

在order-service的启动类添加注解 @EnableFeignClients , 开启OpenFeign的功能.

3.3 编写OpenFeign的客⼾端

 

@FeignClient(value = "product-service",path = "/product")
public interface ProductApi  {

    //方法声明
    @RequestMapping("/{productId}")
    ProductInfo getProductInfo(@PathVariable("productId") Integer productId);

}

@FeignClient 注解作⽤在接⼝上, 参数说明:

name/value:指定FeignClient的名称, 也就是微服务的名称, ⽤于服务发现, Feign底层会使⽤ Spring Cloud LoadBalance进⾏负载均衡. 也可以使⽤ url 属性指定⼀个具体的url.

path: 定义当前FeignClient的统⼀前缀.

3.4 远程调⽤

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProductApi productApi;

    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        ProductInfo productInfo = productApi.getProductById(orderInfo.getProductId());
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

3.5 测试

 

Feign 简化了与HTTP服务交互的过程, 把REST客⼾端的定义转换为Java接⼝, 并通过注解的⽅式来声明请求参数,请求⽅式等信息, 使远程调⽤更加⽅便和间接.

4. OpenFeign参数传递

通过观察, 我们也可以发现, Feign的客⼾端和服务提供者的接⼝声明⾮常相似

接下来演⽰下Feign参数传递的其他⽅式

4.1 传递单个参数

使⽤多个@RequestParam 进⾏参数绑定即可

服务提供⽅ product-service:

方法实现

 

Feign客户端:

方法声明

order-service:

4.2 传递多个参数

使⽤多个@RequestParam 进⾏参数绑定即可

4.3 传递对象

 

 

4.4 传递JSON

 

5. 最佳实践

通过观察, 我们也能看出来, Feign的客⼾端与服务提供者的controller代码⾮常相似

有没有⼀种⽅法可以简化这种写法呢?

5.1 Feign继承方式

Feign ⽀持继承的⽅式, 我们可以把⼀些常⻅的操作封装到接⼝⾥.

我们可以定义好⼀个接⼝, 服务提供⽅实现这个接⼝, 服务消费⽅编写Feign 接⼝的时候, 直接继承这个接⼝

5.1.1 创建一个Model

product-api 

5.1.2 依赖

<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>

5.1.3 接口编写

复制 ProductApi, ProductInfo 到product-api模块中

 

public interface ProductInterface {
    //方法声明
    @RequestMapping("/{productId}")
    ProductInfo getProductById(@PathVariable("productId") Integer productId);

    @RequestMapping("/p1")
    String p1(@RequestParam("id") Integer id);

    @RequestMapping("/p2")
    String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);

    @RequestMapping("/p3")
    String p3(@SpringQueryMap ProductInfo productInfo);

    @RequestMapping("/p4")
    String p4(@RequestBody ProductInfo productInfo);
}

5.1.4 Jar包

通过Maven打包 

5.1.5 服务提供方

服务提供⽅实现接⼝ ProductInterface

 

5.1.6 服务消费方

服务消费⽅继承ProductInterface

 

5.1.7 测试

 

 

5.2 Feign抽取方式

官⽅推荐Feign的使⽤⽅式为继承的⽅式, 但是企业开发中, 更多是把Feign接⼝抽取为⼀个独⽴的模块 (做法和继承相似, 但理念不同).

操作⽅法: 将Feign的Client抽取为⼀个独⽴的模块, 并把涉及到的实体类等都放在这个模块中, 打成⼀个Jar.

服务消费⽅只需要依赖该Jar包即可. 这种⽅式在企业中⽐较常⻅, Jar包通常由服务提供⽅来实现

5.2.1 创建⼀个module

product-api 

5.2.2 依赖

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

5.2.3 编写API

复制 ProductApi, ProductInfo 到product-api模块中

同上 

5.2.4 Jar包

同上 

5.2.5 服务消费⽅使⽤product-api

①删除ProductApi, ProductInfo

②引入依赖

<dependency>
    <groupId>org.example</groupId>
    <artifactId>product-api</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>compile</scope>
</dependency>

修改项⽬中ProductApi, ProductInfo的路径为product-api中的路径

③指定扫描类: ProductApi

在启动类指定需要加载的Feign客⼾端

5.2.6 测试

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值