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 |
---|---|---|
類級別映射 |
| @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<User> searchUsers(UserQuery query) {// 自動處理 ?name=xxx&age=xxx 到query的映射
}// OpenFeign(需要@SpringQueryMap注解)
@FeignClient(name="user-service")
public interface UserClient {@GetMapping("/search")List<User> 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<Product> 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<Product> searchProducts(@SpringQueryMap ProductQuery query);
}// 配置類
@Configuration
public class FeignConfig {// OpenFeign使用的攔截器為 RequestInterceptor@Beanpublic RequestInterceptor authInterceptor() {return template -> template.header("X-Auth", "token123");}
}// 調用示例
@Service
public 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 簡介-筆記