本文目录导读:

下面是一个使用 Spring Cloud OpenFeign 的完整调用案例,包含:
- 服务提供方(生产者)
- 服务消费方(Feign 客户端)
- Feign 接口定义
- 常见的配置(超时、重试、日志等)
项目结构假设
假设我们有两个服务:
order-service:订单服务(生产者)user-service:用户服务(消费者)
用户服务通过 Feign 调用订单服务的接口。
服务提供方(order-service)
1 Controller
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/{id}")
public Order getOrderById(@PathVariable Long id) {
// 模拟返回订单数据
return new Order(id, "订单-" + id, 100.0);
}
@PostMapping
public Order createOrder(@RequestBody Order order) {
System.out.println("创建订单:" + order);
return order;
}
}
2 Model(Order)
public class Order {
private Long id;
private String name;
private Double amount;
// 无参构造、全参构造、getter/setter
}
服务消费方(user-service)
1 引入依赖(pom.xml)
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 可选:负载均衡(如果使用服务发现) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2 启动类开启 Feign
@SpringBootApplication
@EnableFeignClients // 开启 Feign 客户端扫描
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
3 定义 Feign 接口
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
// 调用远程服务 "order-service" 的接口
// name = 服务名(如果是注册中心)或 url = 直接指定地址
@FeignClient(name = "order-service", url = "http://localhost:8081")
public interface OrderFeignClient {
@GetMapping("/orders/{id}")
Order getOrderById(@PathVariable("id") Long id);
@PostMapping("/orders")
Order createOrder(@RequestBody Order order);
}
说明:
name:在注册中心模式下,会从注册中心获取服务名对应的实例列表。url:直接指定地址,适合本地测试或固定地址。- 如果使用注册中心(Nacos/Eureka),可以只写
name,去掉url。
4 在 Service 中调用
@Service
public class UserService {
@Autowired
private OrderFeignClient orderFeignClient;
public Order getOrder(Long id) {
// 直接调用远程接口
return orderFeignClient.getOrderById(id);
}
public Order createOrder(Order order) {
return orderFeignClient.createOrder(order);
}
}
5 Controller 调用测试
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/order/{id}")
public Order getOrder(@PathVariable Long id) {
return userService.getOrder(id);
}
@PostMapping("/order")
public Order createOrder(@RequestBody Order order) {
return userService.createOrder(order);
}
}
配置文件(application.yml)
# 服务端口
server:
port: 8082
# 如果使用注册中心(以 Nacos 为例)
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# Feign 相关配置
feign:
client:
config:
default:
# 连接超时时间(毫秒)
connect-timeout: 5000
# 读取超时时间(毫秒)
read-timeout: 5000
# 日志级别
logger-level: FULL
# 也可以单独为某个服务配置
order-service:
connect-timeout: 3000
read-timeout: 3000
# 开启压缩
compression:
request:
enabled: true
mime-types: application/json
min-request-size: 2048
response:
enabled: true
常见问题与扩展
1 日志输出
开启 Feign 日志需要两个步骤:
- 配置文件中设置
logger-level: FULL - 在配置类或启动类中添加:
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
2 自定义错误处理(Fallback)
实现 OrderFeignClient 的 fallback 类:
@Component
public class OrderFeignClientFallback implements OrderFeignClient {
@Override
public Order getOrderById(Long id) {
// 降级处理
return new Order(-1L, "降级订单", 0.0);
}
@Override
public Order createOrder(Order order) {
return null;
}
}
在 @FeignClient 中指定 fallback:
@FeignClient(name = "order-service", fallback = OrderFeignClientFallback.class)
public interface OrderFeignClient { ... }
3 请求拦截器(添加 Token)
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
requestTemplate.header("Authorization", "Bearer " + getToken());
};
}
运行测试
- 启动
order-service(端口 8081) - 启动
user-service(端口 8082) - 访问
http://localhost:8082/users/order/1,正常返回订单信息。