> 技术文档 > SpringMVC注解与SpringCloudOpenFeign注解对比

SpringMVC注解与SpringCloudOpenFeign注解对比


1. 背景知识

梳理SpringMVC和SpringCloudOpenFeign常用注解后:

  • Spring MVC中常用注解_笔记-CSDN博客
  • Spring Cloud OpenFeign 常用注解_笔记-CSDN博客

这里对两类注解做个对比。理解两者定位(服务端 vs 客户端)是掌握注解使用的关键:

  • Spring MVC注解用于服务端,描述如何解析一个HTTP请求;
  • OpenFeign注解用于客户端,描述如何构造一个HTTP请求(包括URL、参数、头、体等)

2.功能定位对比

特性 Spring MVC 注解 Spring Cloud OpenFeign 注解 定位方向 服务端(接收请求) 客户端(发送请求) 主要功能

处理传入的 HTTP 请求;

路由请求、解析请求参数、处理请求体、渲染响应等。

构建对外的 HTTP 请求;

将 Java 接口转化为 HTTP 请求,发送到远程服务端。

运行位置 服务提供方 服务消费方 典型场景 暴露 REST API 调用其他服务的 REST API

3.核心注解对比

3.1 请求映射

功能 Spring MVC OpenFeign 类级别映射

@RestController

@RequestMapping

@FeignClient 方法级别映射 @GetMapping/@PostMapping 等 @GetMapping/@PostMapping 等 绑定路径变量 @PathVariable @PathVariable(必须显式命名)

3.2 参数处理

参数类型 Spring MVC(获取) OpenFeign(设置) 绑定查询参数 自动绑定 POJO 或 @RequestParam @RequestParam 或 @SpringQueryMap 绑定请求体 @RequestBody @RequestBody 绑定请求头 @RequestHeader(获取请求头) @RequestHeader(在客户端设置请求头发送给服务端) 表单数据 @ModelAttribute 需自定义编码器 文件上传 @RequestPart @RequestPart(需配置编码器)

3.3 特殊功能

功能 Spring MVC OpenFeign 声明 / @FeignClient(Feign特有,声明一个Feign客户端) 对象转查询参数 自动绑定 POJO @SpringQueryMap(Feign特有,用于GET请求传递对象参数) 错误处理 @ExceptionHandler ErrorDecoder 实现 熔断降级 无原生支持(需整合) fallback/fallbackFactory(Feign特有) 请求拦截 HandlerInterceptor RequestInterceptor 配置方式 @ControllerAdvice @EnableFeignClients

4. 关键差异演示

4.1. URL路径差异

//Spring MVC:@RestController@RequestMapping(\"/users\")public class UserController { @GetMapping(\"/{id}\") public User getUser(@PathVariable Long id) { ... }}//Feign接口中必须指定完整路径(包括类上的路径),因为Feign不支持类级别的路径继承@FeignClient(name = \"user-service\")public interface UserClient { @GetMapping(\"/users/{id}\") // 这里必须写完整路径,包括类上没有公共前缀 User getUser(@PathVariable(\"id\") Long id); }

4.2. 参数处理差异 

//Spring MVC 注解用于获取参数(如使用@RequestHeader获取请求头)@PostMapping(\"/users\")public User createUser(@RequestBody User user,@RequestHeader(\"X-Token\") String token){...}// Feign注解用于设置参数(如使用@RequestHeader设置请求头)@FeignClient(name=\"user-service\")public interface UserClient {@PostMapping(\"/users\")User createUser(@RequestBody User user,@RequestHeader(\"X-Token\") String token);}

4.3. 路径变量处理差异

// Spring MVC(支持隐式绑定)@GetMapping(\"/orders/{orderId}/items/{itemId}\")public Item getItem(@PathVariable Long orderId,  @PathVariable String itemId) {...}// OpenFeign(@PathVariable 必须显式命名)@FeignClient(name=\"order-service\")public interface OrderClient { @GetMapping(\"/orders/{orderId}/items/{itemId}\") Item getItem(@PathVariable(\"orderId\") Long orderId,  @PathVariable(\"itemId\") String itemId);}

4.4. 查询参数处理差异

// Spring MVC(自动绑定POJO)@GetMapping(\"/search\")public List searchUsers(UserQuery query) { // 自动处理 ?name=xxx&age=xxx 到query的映射}// OpenFeign(需要@SpringQueryMap注解)@FeignClient(name=\"user-service\")public interface UserClient { @GetMapping(\"/search\") List searchUsers(@SpringQueryMap UserQuery query); //需要使用@SpringQueryMap注解构建query到 ?name=xxx&age=xxx 的映射}

5. 二者协作演示

服务A:使用Spring MVC暴露API,服务端

// 服务A(使用Spring MVC暴露API,服务端)@RestController@RequestMapping(\"/products\")public class ProductController { @GetMapping(\"/{id}\") public Product getProduct(@PathVariable Long id) { // 返回产品信息 } @GetMapping(\"/search\") public List searchProducts(ProductQuery query) { // 返回产品列表信息 }}

服务B:使用OpenFeign调用服务A, 客户端

// 服务B(使用OpenFeign调用服务A, 客户端)@FeignClient(name = \"product-service\", configuration = FeignConfig.class)public interface ProductClient { @GetMapping(\"/products/{id}\") Product getProduct(@PathVariable(\"id\") Long id); @PostMapping(\"/products/search\") List searchProducts(@SpringQueryMap ProductQuery query);}// 配置类@Configurationpublic class FeignConfig { // OpenFeign使用的拦截器为 RequestInterceptor @Bean public RequestInterceptor authInterceptor() { return template -> template.header(\"X-Auth\", \"token123\"); }}// 调用示例@Servicepublic class OrderService { private final ProductClient productClient; public Product getProductForOrder(Long productId) { return productClient.getProduct(productId); }}

6.相关阅读

  • Spring MVC中常用注解_笔记
  • Spring Cloud OpenFeign 常用注解_笔记
  • Spring MVC拦截器:HandlerInterceptor介绍-笔记
  • OpenFeign拦截器:feign.RequestInterceptor 简介-笔记