【OpenFeign】基础使用

发布于:2025-09-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

1. Feign介绍

1.什么是 Feign

Feign 是 Netflix 开发的一个 声明式的 HTTP 客户端,在 Spring Cloud 中被广泛使用。它的目标是:让我们调用远程 HTTP API 的方式,像调用本地接口一样简单。

换句话说:

  • 不用手写 RestTemplate 的各种请求
  • 只要定义一个接口 + 注解,Spring Cloud Feign 就会帮你生成实现类,并通过 HTTP 调用对应的远程服务。

2.Feign 的核心特点

  • 声明式调用:只需在接口上加注解 (@FeignClient),不用写具体实现。

  • 与 Spring Cloud 集成:能和 Eureka、Nacos 等注册中心结合,实现服务发现。

  • 内置负载均衡:在 Spring Cloud Netflix 时代默认结合 Ribbon,现在一般结合 Spring Cloud LoadBalancer。

  • 支持拦截器:可以统一处理请求头(如 token)、日志打印、重试等。

  • 支持编码解码:内置 JSON 编解码,可以和 Jackson、Gson 等整合。

3.Feign 的发展

Netflix Feign(早期版本):最初由 Netflix 开发,后被 Spring Cloud 整合。
OpenFeign(现在常用的版本):Spring Cloud 现在默认使用的是 Spring Cloud OpenFeign,它是对 Feign 的增强版本。

1.1 使用示例

假设有一个 user-service 提供 REST 接口:

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "张三");
    }
}

在另一个服务(比如 order-service)中,我们要调用 user-service:
① 定义 Feign 接口

@FeignClient(name = "user-service")  // user-service 是注册在 Nacos/Eureka 上的服务名
public interface UserClient {

    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id") Long id);
}

② 注入并调用

@Service
public class OrderService {

    @Autowired
    private UserClient userClient;

    public void createOrder(Long userId) {
        User user = userClient.getUserById(userId); // 直接像调用本地方法一样
        System.out.println("下单用户: " + user.getName());
    }
}

这样,Feign 就会帮你把 getUserById() 变成 HTTP 调用。

1.2 Feign与RPC对比

特性 Feign(HTTP 客户端) RPC(Dubbo/gRPC 等)
协议 HTTP/HTTPS (REST) TCP/HTTP2/自定义协议
序列化方式 JSON / XML Protobuf / Hessian / Thrift
调用方式 HTTP 请求,返回 JSON 远程方法调用(接近本地调用)
性能 中等(HTTP+JSON 有开销) 高效(协议二进制、TCP直连)
跨语言支持 很好(所有语言都支持 HTTP) 较好(需官方 SDK,如 gRPC)
常见场景 Web 微服务调用 高性能微服务 / 内部系统调用

1.3 SpringCloud Alibaba快速整合OpenFeign

1.引入依赖

在这里插入图片描述
2.编写调用接口+@FeignClient注解
在这里插入图片描述
3.调用端在启动类上添加@EnableFeignClients注解
在这里插入图片描述
4.发起调用,像本地方法一样调用

1.3.1 详细代码

在这里插入图片描述

调用方

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.beijing</groupId>
        <artifactId>springcloudalibaba</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.beijing</groupId>
    <artifactId>order-openFeign</artifactId>
    <version>1.0.1-SNAPSHOT</version>
    <name>order</name>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- 添加openFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

    </dependencies>

</project>
server:
  port: 14031

management:
  endpoints:
    web:
      exposure:
        include=*:

spring:
  application:
    name: order-openFeign
  cloud:
    nacos:
      discovery:
        server-addr: 115.190.126.xxx:8848
        namespace: prod
        group: demo-1
package com.beijing.controller;

import com.beijing.order.feign.StockFeignService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author aaa
 * @version 1.0
 * @date 2025/08/27
 */
@RestController
@RequestMapping("/order")
public class OrderController {
    @Resource
    private StockFeignService stockFeignService;

    @RequestMapping("/add")
    public String add() {

        String reduct = stockFeignService.reduct();

        return "add order" + reduct;
    }
}

package com.beijing;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author aaa
 * @version 1.0
 * @date 2025/08/27
 */
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class OrderFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignApplication.class, args);
    }
}

package com.beijing.order.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(name = "stock", path = "/stock")
public interface StockFeignService {

    @RequestMapping("/reduct")
    public String reduct();
}


被调用方

package com.beijing;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @author aaa
 * @version 1.0
 * @date 2025/08/27
 */
@EnableDiscoveryClient
@SpringBootApplication
public class StockApplication {
    public static void main(String[] args) {
        SpringApplication.run(StockApplication.class, args);
    }
}
package com.beijing.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author fanzhen@ict.ac.cn
 * @version 1.0
 * @date 2025/08/27
 */
@RestController
@RequestMapping("/stock")
public class StockController {

    @RequestMapping("/reduct")
    public String reduct() {
        System.out.println("扣减库存开始");
        return "扣减库存成功";
    }
}
server:
  port: 14029

management:
  endpoints:
    web:
      exposure:
        include=*:

spring:
  application:
    name: stock
  cloud:
    nacos:
      discovery:
        server-addr: 115.190.126.xxx:8848
        namespace: prod
        group: demo-1

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.beijing</groupId>
        <artifactId>springcloudalibaba</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.beijing</groupId>
    <artifactId>stock</artifactId>
    <version>1.0.1-SNAPSHOT</version>
    <name>stock</name>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

</project>

网站公告

今日签到

点亮在社区的每一天
去签到