当前位置: 首页 > news >正文

spring mvc中不同服务调用类型(声明式(Feign)、基于模板(RestTemplate)、基于 SDK、消息队列、gRPC)对比详解

@RestControllerAdvice 和 @ControllerAdvice 对比详解


1. 基本概念
注解等效组合核心作用
@ControllerAdvice@Component + @RequestMapping(隐式)定义全局控制器增强类,处理跨控制器的异常、数据绑定或全局响应逻辑。
@RestControllerAdvice@ControllerAdvice + @ResponseBody继承 @ControllerAdvice,并默认将返回值序列化为 HTTP 响应体(如 JSON)。

2. 核心区别
对比维度@ControllerAdvice@RestControllerAdvice
返回值处理默认返回视图名称(需配合 @ResponseBody 才能序列化)直接返回数据对象,自动序列化为响应体(如 JSON)
适用场景传统 MVC 应用(如返回 HTML 视图或混合响应)RESTful API(需返回 JSON/XML 格式数据)
注解组合需手动添加 @ResponseBody 才能返回 JSON内置 @ResponseBody,无需额外声明
返回类型示例String(视图名称)、ModelAndViewResponseEntity, Map, 自定义 POJO

3. 代码示例对比
场景:全局异常处理

@ControllerAdvice 示例(返回视图名称)

@ControllerAdvice
public class GlobalViewExceptionHandler {
    @ExceptionHandler(IOException.class)
    public String handleIOException() {
        return "error/500"; // 返回视图名称(如 Thymeleaf 模板)
    }
}

@RestControllerAdvice 示例(返回 JSON)

@RestControllerAdvice
public class GlobalApiExceptionHandler {
    @ExceptionHandler(IOException.class)
    public ResponseEntity<ErrorDetails> handleIOException() {
        ErrorDetails error = new ErrorDetails(500, "Internal Server Error", null);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }
}

4. 关键功能对比
功能@ControllerAdvice@RestControllerAdvice
异常处理支持,需手动定义返回类型(视图或 JSON)支持,直接返回 JSON 格式错误对象
数据绑定可通过 @InitBinder 统一配置绑定规则同样支持 @InitBinder,但返回值默认序列化
全局方法增强可通过 @ModelAttribute 注入公共数据同样支持,但返回数据自动序列化
响应体控制需显式使用 @ResponseBodyResponseEntity内置 @ResponseBody,无需额外声明

5. 配置与扩展
共同特性
  • 包级作用域:通过 basePackages 指定需要增强的控制器包:

    @ControllerAdvice(basePackages = "com.example.controllers")
    
  • 方法级过滤:通过 annotations 指定仅处理特定注解的控制器:

    @ControllerAdvice(annotations = RestController.class)
    
差异点
  • 响应体格式
    • @ControllerAdvice 需显式配置 @ResponseBodyResponseEntity 才能返回 JSON:

      @ControllerAdvice
      public class MixHandler {
          @ResponseBody // 显式声明返回 JSON
          @ExceptionHandler(IOException.class)
          public ErrorDetails handleIOException() { ... }
      }
      
    • @RestControllerAdvice 默认支持序列化:

      @RestControllerAdvice
      public class ApiHandler {
          @ExceptionHandler(IOException.class)
          public ErrorDetails handleIOException() { ... } // 自动序列化为 JSON
      }
      

6. 典型使用场景
场景推荐注解原因
传统 Web 应用(返回 HTML)@ControllerAdvice需返回视图名称(如 Thymeleaf 模板路径)。
RESTful API 异常处理@RestControllerAdvice直接返回结构化的 JSON 错误信息,无需额外配置 @ResponseBody
混合场景(需同时处理视图和 JSON)@ControllerAdvice需通过 @ResponseBody 区分返回类型,或使用 ResponseEntity 控制响应格式。

7. 总结表格
维度@ControllerAdvice@RestControllerAdvice
核心作用全局异常处理、数据绑定、视图增强专为 REST API 设计,返回 JSON 格式响应
返回值默认行为返回视图名称或需 @ResponseBody 显式声明直接返回数据对象,自动序列化为响应体
适用场景传统 MVC 应用、混合响应场景纯 REST API 开发(如 Spring Boot 微服务)
注解组合关系独立注解,需手动配置响应格式等效于 @ControllerAdvice + @ResponseBody

关键总结### 声明式服务调用与其他服务调用类型对比详解


1. 什么是声明式服务调用?

定义:通过注解或配置声明服务调用接口,无需手动编写底层网络请求代码,由框架自动生成代理实现。
核心特点

  • 声明式:通过注解(如 @FeignClient)或配置定义服务接口。
  • 自动代理:框架(如 Spring Cloud Feign)自动处理 HTTP 请求、序列化、负载均衡等。
  • 解耦:开发者只需关注业务逻辑,无需关心网络细节。

示例(Spring Cloud Feign):

@FeignClient(name = "service-provider") // 声明调用的服务名称
public interface ProductClient {
    @GetMapping("/products/{id}")
    Product getProduct(@PathVariable("id") String id);
}

2. 其他服务调用类型及对比

类型 1:基于模板的调用(如 RestTemplate/HttpClient)

定义:手动构造 HTTP 请求,通过模板工具(如 RestTemplateOkHttp)发送请求并处理响应。
特点

  • 灵活控制:可完全控制请求参数、超时、重试等。
  • 无侵入性:无需框架支持,纯 Java 实现。
  • 代码冗长:需手动处理异常、序列化等。

使用方法

// 使用 RestTemplate 调用服务
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Product> response = restTemplate.getForEntity(
    "http://service-provider/products/123",
    Product.class
);
Product product = response.getBody();

类型 2:基于 SDK 的调用

定义:通过第三方或自定义 SDK 封装服务调用逻辑,提供统一接口。
特点

  • 封装复杂逻辑:如 AWS SDK 封装了 S3、DynamoDB 的调用细节。
  • 依赖性强:需引入 SDK 依赖,版本需与服务端兼容。
  • 易用性高:开发者无需关心底层协议。

使用示例(AWS S3 SDK)

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
    .withRegion("us-west-2")
    .build();
S3Object object = s3Client.getObject("my-bucket", "key-name");

类型 3:基于消息队列的异步调用

定义:通过消息中间件(如 RabbitMQ、Kafka)发送异步消息,由消费者处理。
特点

  • 解耦:生产者与消费者无直接依赖。
  • 异步:支持高并发和最终一致性。
  • 需消息中间件:需维护消息队列基础设施。

使用示例(Spring Cloud Stream)

// 生产者发送消息
@Service
public class OrderService {
    @Autowired
    private MessageChannel orderChannel;

    public void sendOrder(Order order) {
        orderChannel.send(MessageBuilder.withPayload(order).build());
    }
}

// 消费者处理消息
@Service
public class OrderConsumer {
    @StreamListener("order-inbound")
    public void processOrder(Order order) {
        // 处理订单逻辑
    }
}

类型 4:基于 gRPC 的调用

定义:使用 gRPC 框架进行高性能的 RPC 调用,基于 Protocol Buffers 定义接口。
特点

  • 高性能:二进制协议,支持流式传输。
  • 强类型定义:通过 .proto 文件定义接口和数据结构。
  • 学习成本高:需掌握 gRPC 和 Protocol Buffers。

使用示例

// 定义 proto 文件
service ProductService {
    rpc GetProduct (ProductRequest) returns (ProductResponse) {}
}

// 生成客户端代码
ProductServiceBlockingStub stub = ProductGrpc.newBlockingStub(channel);
ProductResponse response = stub.getProduct(request);

类型 5:基于 HTTP 客户端(如 OkHttp)的直接调用

定义:直接使用低层 HTTP 客户端(如 OkHttp、URLConnection)发送请求。
特点

  • 完全控制:可配置超时、连接池等。
  • 无需框架依赖:纯 Java 实现。
  • 代码复杂度高:需手动处理序列化、异常等。

示例(OkHttp)

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
    .url("http://service-provider/products/123")
    .build();
Response response = client.newCall(request).execute();
String responseBody = response.body().string();

3. 对比总结表格
类型声明式基于模板基于 SDK消息队列gRPC
核心特点注解声明,框架代理手动构造请求封装第三方接口异步解耦高性能 RPC
代码复杂度简单(无需手动请求)中等(需处理细节)简单(依赖 SDK)中等(需消息配置)高(需 proto 定义)
适用场景微服务内同步调用需灵活控制的场景第三方服务调用解耦异步场景高性能同步 RPC
框架依赖Spring Cloud无(需 RestTemplate)SDK 依赖RabbitMQ/KafkagRPC 库
是否同步/异步同步(可配置异步)同步/异步同步/异步异步同步/异步流
典型工具FeignRestTemplate,OkHttpAWS SDKSpring Cloud StreamgRPC

4. 选择依据
需求场景推荐类型原因
快速集成微服务同步调用声明式(Feign)零代码实现负载均衡、熔断,开发效率高。
需灵活控制 HTTP 请求细节基于模板(RestTemplate)直接控制超时、重试等参数。
调用第三方服务(如 AWS)基于 SDK使用官方 SDK 确保兼容性和易用性。
解耦服务间依赖消息队列异步通信,高并发场景下避免阻塞。
高性能低延迟的 RPC 调用gRPC二进制协议和流式传输适合高频、低延迟场景。

5. 关键总结
  1. 声明式服务调用(如 Feign):开发效率最高,适合微服务内同步调用。
  2. 基于模板/SDK灵活性与易用性平衡,适合复杂或第三方服务调用。
  3. 消息队列解耦与异步的首选方案。
  4. gRPC高性能场景的最优选择,需权衡学习成本。

根据项目需求(如性能、耦合度、开发效率),选择合适的调用方式,或混合使用多种类型以满足不同场景。

  1. 选择原则
    • REST API:优先使用 @RestControllerAdvice,简化 JSON 响应处理。
    • 传统 MVC:使用 @ControllerAdvice,灵活控制视图或 JSON 响应(需配合 @ResponseBody)。
  2. 注意事项
    • @ControllerAdvice 若需返回 JSON,必须显式添加 @ResponseBody 或使用 ResponseEntity
    • @RestControllerAdvice 内置 @ResponseBody,无需额外声明,适合统一 API 响应格式。
  3. 最佳实践
    • 对于纯 API 项目,用 @RestControllerAdvice 集中处理异常和响应。
    • 在混合项目中,通过 basePackages 区分不同场景的增强类。

相关文章:

  • 【Proteus仿真】【32单片机-A008】MPX4115压力检测系统设计
  • Linux环境防火墙常用配置说明
  • UGUI源代码之Text—实现自定义的字间距属性
  • AutoModelForCausalLM 解析,因果模型
  • MyBatis中特殊符号处理总结
  • 安卓性能调优之-检测应用启动速度
  • 在Flutter中使用BottomNavigationBar和IndexedStack可以实现一个功能完整的底部导航栏
  • 适用于恶劣工业环境的高功率PoE+网管交换机
  • 状态管理组件Pinia 简介与底层原理 、Pinia 与其他状态管理库对比、Vue3 + Element Plus + Pinia 安装配置详解
  • DAPP实战篇:使用ethers.js连接以太坊智能合约
  • 数字图像相关(DIC)技术在土木行业的部分应用
  • 将已有 SVN 服务打包成 Docker 镜像的详细步骤
  • 蓝桥杯 区间排序
  • git操作0409
  • ruby self
  • 探索 Shell 中的扩展通配符:从 Bash 到 Zsh
  • ​​AMS行政管理系统:数字化赋能人力资源精益管理​
  • LeetCode 252 会议室题全解析:Swift 实现 + 场景还原
  • Cherry Studio配置MCP server
  • 记录学习的第二十四天
  • wap移动建站系统/百度竞价投放
  • 惠州建设网站开发/网页设计主题参考
  • 徐州服饰网站建设/包括哪些内容
  • asp网站如何安装/欧洲站fba
  • h5响应式网站设计方案/策划推广
  • 莲湖区建设局网站/关于进一步优化 广州