基于Spring 6.1 RestClient构建高可用声明式HTTP客户端方案详解

 更新时间:2026年01月16日 10:14:49   作者:越重天  
文章介绍了如何基于Spring 6.1的RestClient构建高可靠声明式HTTP客户端,解决了传统RestTemplate的诸多问题,包括同步调用、负载均衡和安全令牌透传等,通过一系列代码示例和解析,感兴趣的朋友跟随小编一起看看吧

告别Feign:基于Spring 6.1 RestClient构建高可靠声明式HTTP客户端

引言

在微服务架构持续演进的今天,高效的远程服务通信始终是系统设计的核心挑战之一。传统的Spring生态中,RestTemplate长期作为同步HTTP客户端的首选,但其阻塞式模型、繁琐的配置方式以及与现代云原生架构的兼容性问题逐渐显露。随着Spring Framework 6.1的发布,全新的RestClient以更简洁的API设计、更强大的扩展能力登上舞台,标志着Spring在同步HTTP客户端领域的一次革新。

本文聚焦于如何基于Spring Framework 6.1+ 的新特性,构建一套生产级的声明式HTTP通信方案。我们将深入探讨以下核心命题:在非响应式架构下,如何通过RestClient.Builder实现媲美Feign的声明式接口?如何无缝集成Spring Cloud LoadBalancer实现智能负载均衡?如何在同步调用链路中实现安全令牌的自动透传?这些问题的答案不仅关乎代码的优雅性,更直接影响着微服务系统的性能、可维护性和扩展性。

通过剖析RestClient的设计哲学,读者将掌握三大关键技术:

  • 其一,声明式接口驱动开发,借助@HttpExchange注解实现类Feign的简洁定义,告别冗余的模板代码;
  • 其二,深度集成Spring Cloud生态,通过定制ClientHttpRequestInterceptor打通服务发现与负载均衡链路,彻底解决“503 Service Unavailable”和403等典型问题;
  • 其三,工业级连接池配置,基于Apache HttpClient5的精细化连接管理策略,确保高并发场景下的稳定吞吐。

文章还将揭示Spring 6.1+中鲜为人知的高级特性:例如如何通过RestClientAdapter实现与声明式接口的无缝对接,将帮助开发者在传统WebMVC架构中,以零侵入改造的成本,获得接近响应式编程的性能表现。

对于正在面临以下痛点的团队,本文提供了一站式解决方案:

  • 遗留系统需要从RestTemplate向现代客户端迁移。
  • 同步服务调用存在性能瓶颈或连接泄漏问题
  • 需要统一管理多服务的负载均衡与安全认证。
  • 期望在不引入响应式编程的前提下优化资源利用率。

一、环境准备(pom.xml)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>6.1.0+</version> <!-- 必须6.1+ -->
</dependency>

二、声明式HTTP接口定义

/**  
 * <pre>
 *  调用远程同步角色权限服务
 *    注:http://horus/horus这个配置,非常关键:
 *       1. 第一个horus表示远程服务应用的名字(注册到nacos注册中心的应用名,运行期间会被负载均衡拦截并替换成实际的ip和端口)
 *       2. 第二个horus配置表示远程服务的base上下文路径,即contextPath,如果远程应用不带上下文路径,这里配置成http://horus即可
 * </pre>
 * @author sinhy
 * @since 2022-07-13 17:00
 * @version V1.0  
 */
@HttpExchange(url = "http://horus/horus")
public interface AuthoritySyncSDKService
{
    /**
     * 同步角色权限
     * @author sinhy
     * @since 2022-07-13 16:06  void
     */
    @PostExchange("/syncRoleAuthority")
    void syncRoleAuthority();
}

三、同步RestClient配置

@Configuration
public class HttpExchangeFluxConfiguration
{
    /**
     *  @LoadBalanced负载均衡注入,此注解用于标记RestTemplate、RestClient或WebClient.Builder这几类对象。将生成器bean配置为使用LoadBalancerClient。
     * @author lilinhai
     * @since 2025-04-15 16:23 
     * @return WebClient.Builder
     */
    @LoadBalanced
    @Bean
    public RestClient.Builder loadBalancedWebClientBuilder()
    {
        return RestClient.builder().requestFactory(new HttpComponentsClientHttpRequestFactory(httpClient()));
    }
    @Bean
    public TokenPropagationExchangeFilterFunction tokenFilter()
    {
        return new TokenPropagationExchangeFilterFunction();
    }
    @Bean
    public HttpServiceProxyFactory httpServiceProxyFactory(RestClient.Builder restClientBuilder, TokenPropagationExchangeFilterFunction tokenFilter)
    {
        restClientBuilder.requestInterceptor(tokenFilter);
        RestClient restClient = restClientBuilder.build();
        return HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build();
    }
    private PoolingHttpClientConnectionManager poolingConnManager()
    {
        PoolingHttpClientConnectionManager pool = new PoolingHttpClientConnectionManager();
        // 最大连接数
        pool.setMaxTotal(200);
        // 每个路由的最大连接数
        pool.setDefaultMaxPerRoute(50);
        return pool;
    }
    private HttpClient httpClient()
    {
        return HttpClients.custom()
            .setConnectionManager(poolingConnManager())
            .setConnectionReuseStrategy(new DefaultClientConnectionReuseStrategy())
            .evictExpiredConnections()
            .evictIdleConnections(TimeValue.ofSeconds(30))
            .build();
    }
}

四、Token透传实现(同步拦截器)

/**  
 * 令牌透传过滤器
 * @author lilinhai
 * @since 2025-04-15 14:35
 * @version V1.0  
 */
public class TokenPropagationExchangeFilterFunction implements ClientHttpRequestInterceptor
{
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
    {
        // 设置授权信息
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        if (ra != null)
        {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) ra;
            String clientInfoJsonStr = servletRequestAttributes.getRequest().getHeader(WebHttpConstant.CLIENT_INFO_HEADER_NAME);
            if (clientInfoJsonStr != null)
            {
                request.getHeaders().add(WebHttpConstant.CLIENT_INFO_HEADER_NAME, clientInfoJsonStr);
            }
            String acceptLanguage = servletRequestAttributes.getRequest().getHeader(HttpHeaders.ACCEPT_LANGUAGE);
            if (acceptLanguage != null)
            {
                request.getHeaders().add(HttpHeaders.ACCEPT_LANGUAGE, acceptLanguage);
            }
        }
        return execution.execute(request, body);
    }
}

五、控制器层使用示例

@RestController
@RequestMapping("/authority")
public class AuthoritySyncController {
    private final AuthoritySyncSDKService authoritySyncSDKService;
    public AuthoritySyncController(AuthoritySyncSDKService authoritySyncSDKService)
    {
        this.authoritySyncSDKService = authoritySyncSDKService;
    }
    @GetMapping("/sync")
    public void sync() {
        authoritySyncSDKService.syncRoleAuthority();
    }
}

六、核心机制解析

  • 负载均衡流程
    • 通过自定义ClientHttpRequestInterceptor实现服务发现
    • 使用LoadBalancerClient.choose()获取服务实例
    • 重写请求URI为实际IP:Port
  • 声明式接口原理
    • HttpServiceProxyFactory基于JDK动态代理生成实现类
    • 底层使用RestClient执行实际HTTP请求
  • 与RestTemplate方案的差异
    • 更现代的流式API配置方式
    • 原生支持URI重写拦截器链
    • 更好的异常处理机制

七、方案优势

  1. 官方推荐:完全基于Spring 6.1+官方组件栈
  2. 性能优化:底层使用HttpComponents连接池
  3. 配置灵活:支持细粒度的超时和连接管理
  4. 未来兼容:为迁移到响应式架构保留接口兼容性

注意事项

  1. 确保服务调用URL格式为http://service-name/path
  2. Spring Security配置需要正确设置SecurityContextHolder策略
  3. 生产环境建议启用spring-cloud-starter-circuitbreaker-resilience4j实现熔断

到此这篇关于基于Spring 6.1 RestClient构建高可用声明式HTTP客户端方案详解的文章就介绍到这了,更多相关Spring RestClient声明式http客户端内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一不小心就让Java开发踩坑的fail-fast是个什么鬼?(推荐)

    一不小心就让Java开发踩坑的fail-fast是个什么鬼?(推荐)

    这篇文章主要介绍了Java fail-fast,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java操作Redis2种方法代码详解

    Java操作Redis2种方法代码详解

    这篇文章主要介绍了Java操作Redis2种方法代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • SpringBoot加载外部依赖过程解析

    SpringBoot加载外部依赖过程解析

    这篇文章主要介绍了SpringBoot加载外部依赖过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决

    java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决

    这篇文章主要给大家介绍了关于java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决的相关资料,数组越界访问是一个非常严重的问题,文中通过图文将解决的办法介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • java web支持jsonp的实现代码

    java web支持jsonp的实现代码

    这篇文章主要介绍了java web支持jsonp的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 一篇文章带你了解Java方法的使用

    一篇文章带你了解Java方法的使用

    这篇文章主要给大家介绍了关于Java中方法使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Java设计模式之策略模式_动力节点Java学院整理

    Java设计模式之策略模式_动力节点Java学院整理

    策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。接下来通过本文给大家分享Java设计模式之策略模式,感兴趣的朋友一起看看吧
    2017-08-08
  • Java无界阻塞队列DelayQueue详细解析

    Java无界阻塞队列DelayQueue详细解析

    这篇文章主要介绍了Java无界阻塞队列DelayQueue详细解析,DelayQueue是一个支持时延获取元素的无界阻塞队列,队列使用PriorityQueue来实现,队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素,需要的朋友可以参考下
    2023-12-12
  • Java8 HashMap遍历方式性能探讨

    Java8 HashMap遍历方式性能探讨

    JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历
    2021-09-09
  • Java面向程序的三大特性之封装、继承、多态详解(最新整理)

    Java面向程序的三大特性之封装、继承、多态详解(最新整理)

    面向对象程序三大特性:封装、继承、多态,而类和对象阶段,主要研究的就是封装特性,何为封装呢?简单来说就是套壳屏蔽细节,本文给大家介绍Java面向程序的三大特性之封装、继承、多态,感兴趣的朋友一起看看吧
    2025-06-06

最新评论