当前位置:首页 > 技术 > 正文内容

Spring 6 引入 HTTP 接口特性替代 Feign

访客 技术 2026年7月3日 1

基于 Spring 6 的声明式 HTTP 客户端新实践

Spring 6 的首个正式版本带来了显著的架构演进,其中最值得关注的是引入了原生的 HTTP 接口(HTTP Interface) 特性。该功能旨在以更简洁、类型安全的方式实现远程服务调用,逐步取代传统如 Feign 等第三方解决方案,推动 HTTP 客户端开发标准化。

快速构建一个演示项目

首先创建一个基础的 Spring Boot 应用作为模拟后端服务。定义一个简单的用户实体类:

public class UserInfo implements Serializable {
    private int id;
    private String username;

    // 构造函数、getter、setter 省略
    @Override
    public String toString() {
        return id + ":" + username;
    }
}

对应提供一个 REST 接口用于返回用户列表:

@GetMapping("/api/users")
public List<UserInfo> fetchAllUsers() {
    return IntStream.rangeClosed(1, 10)
            .mapToObj(i -> new UserInfo(i, "User" + i))
            .collect(Collectors.toList());
}

确保启动后可通过 http://localhost:8080/api/users 正常访问数据。

配置前端客户端工程

新建一个 Spring Boot 3.0+ 工程(对应 Spring Framework 6),并启用 Java 17 及以上版本。在依赖中引入以下模块:

  • spring-web
  • spring-web-reactive

说明:当前版本仅支持基于 Reactive 模型的 WebClient 适配器。

定义声明式接口

创建一个接口来描述远程调用行为:

public interface RemoteUserService {
    @HttpExchange(url = "/api/users", method = "GET")
    List<UserInfo> fetchUserList();
}

所有注解均位于 org.springframework.web.service.annotation 包下,@HttpExchange 是核心标记,支持多种方法映射。

实例化并执行请求

在测试类中通过工厂模式创建代理实例:

@Test
void testFetchUsers() {
    WebClient webClient = WebClient.builder()
            .baseUrl("http://localhost:8080/")
            .build();

    HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(
            WebClientAdapter.forClient(webClient)
    ).build();

    RemoteUserService client = factory.createClient(RemoteUserService.class);
    List<UserInfo> users = client.fetchUserList();

    users.forEach(System.out::println);
}

运行结果将输出 10 条用户信息,验证调用成功。

注解机制详解

@HttpExchange 支持丰富的配置选项,包括:

  • url: 请求路径(可含占位符)
  • method: HTTP 方法(默认为自动推断)
  • contentType: 请求体内容类型
  • accept: 响应期望的 MIME 类型

此外,还支持与 Spring MVC 相同的参数绑定能力,例如:

@HttpExchange(url = "/api/users/{id}", method = "GET")
UserInfo getUserById(@PathVariable("id") int userId);

代理对象生成原理

创建的接口实例并非普通实现类,而是一个由 Spring 动态生成的 AOP 代理对象。它在运行时拦截方法调用,并通过底层的 WebClient 发起实际网络请求。

虽然目前需手动使用 HttpServiceProxyFactory,但未来版本预计会引入类似 @EnableHttpClients 这类便捷注解,进一步降低使用门槛。

为何必须依赖 reactive 模块?

尽管可以使用同步风格编写代码,但当前实现强制依赖 spring-web-reactive,因为其底层采用 WebClient 作为唯一内置适配器。这是由于 Spring 6 对响应式编程的支持是优先级最高的设计方向。

后续版本可能推出基于 RestTemplate 的替代方案,但短期内仍以异步非阻塞模型为主流。

其他高级特性

  • 支持泛型返回值
  • 自定义异常处理器(通过 @Error 注解)
  • @RequestBody@RequestParam 等注解兼容
  • 可结合 @RequestHeader@CookieValue 等完成完整请求构建

总结

随着 Spring 6 推出内建的声明式 HTTP 客户端能力,开发者不再需要引入外部库(如 Feign)即可实现高效、类型安全的服务间通信。这一变化标志着 Spring 正在统一和简化远程调用生态,使开发者更聚焦于业务逻辑本身。

未来版本将持续优化易用性,建议关注官方动态,及时掌握最新进展。

标签: Spring 6

相关文章

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。