Spring6之HTTP Interface分析

news2025/3/1 11:28:38

文章目录

  • 1 HTTP Interface
    • 1.1 引言
    • 1.2 示例
      • 1.2.1 创建服务端
      • 1.2.2 SpringBoot工程
    • 1.3 深入分析
      • 1.3.1 GetExchange(HttpExchange)
      • 1.3.2 UserApiService 实例创建
    • 1.4 其他特性

1 HTTP Interface

1.1 引言

近期,Spring 6 的第一个 GA 版本发布了,其中带来了一个新的特性——HTTP Interface。这个新特性,可以让开发者将 HTTP 服务,定义成一个包含特定注解标记的方法的 Java 接口,然后通过对接口方法的调用,完成 HTTP 请求。看起来很像使用 Feign 来完成远程服务调用,下面我们参考官方文档来完成一个 Demo

1.2 示例

1.2.1 创建服务端

首先创建一个简单的 HTTP 服务,这一步可以创建一个简单的 Spring Boot 工程来完成。

先创建一个实体类:

public class User implements Serializable {

    private int id;
    private String name;
    // 省略构造方法、Getter和Setter
    @Override
    public String toString() {
        return id + ":" + name;
    }
}

再写一个简单的 Controller:

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

确保启动服务之后,能够从http://localhost:8080/users地址获取到一个包含十个用户信息的用户列表。

1.2.2 SpringBoot工程

下面我们新建一个 SpringBoot 工程
在这里插入图片描述

这里需要注意,Spring Boot 的版本至少需要是 3.0.0,这样它以来的 Spring Framework 版本才是 6.0 的版本,才能够包含 HTTP Interface 特性,另外,Spring Framework 6.0Spring Boot 3.0 开始支持的 Java 版本最低是 17,因此,需要选择至少是 17 的 Java 版本。
另外,需要依赖 Spring WebSpring Reactive Web 依赖

创建好新的 SpringBoot 工程后,首先需要定义一个 HTTPInterface 接口。最简单的定义如下即可:

public interface UserApiService {
    @GetExchange("/users")
    List<User> getUsers();
}

然后,我们可以写一个测试方法。

@Test
void getUsers() {
   WebClient client = WebClient.builder().baseUrl("http://localhost:8080/").build();
   HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
   UserApiService service = factory.createClient(UserApiService.class);
   List<User> users = service.getUsers();
   for (User user : users) {
      System.out.println(user);
   }
}

最终回打印获取到的是个用户信息:

1:User1
2:User2

9:User9
10:User10

以上是一个最简单的示例,下面我们看看其中的一些细节。

1.3 深入分析

1.3.1 GetExchange(HttpExchange)

上文例子中的 GetExchange 注解代表这个方法代替执行一个 HTTP Get 请求,与此对应,Spring 还包含了其他类似的注解:
在这里插入图片描述

这些注解定义在spring-web模块的org.springframework.web.service.annotation包下,除了 HttpExchange 之外,其他的几个都是 HttpExchange 的特殊形式,这一点与 Spring MVC 中的 RequestMapping/GetMapping 等注解非常相似。

以下是 HttpExchange 的源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective(HttpExchangeReflectiveProcessor.class)
public @interface HttpExchange {

    @AliasFor("url")
    String value() default "";

    @AliasFor("value")
    String url() default "";

    String method() default "";

    String contentType() default "";

    String[] accept() default {};

}

在上面的例子中,我们只指定了请求的资源路径。

1.3.2 UserApiService 实例创建

在上面例子中,我们定义的 HTTP Interface 接口是 UserApiService,在测试方法中,我们通过 HttpServiceProxyFactory 创建了 UserApiService 的实例,这是参考了 Spring 的官方文档的写法。
也可以将创建的过程写到一个 @Bean 方法中,从而可以将创建好的实例注入到其他的组件中。

我们再定义 UserApiService 的时候,只是声明了一个接口,那具体的请求操作是怎么发出的呢,我们可以通过 DEBUG 模式看得出来,这里创建的 UserApiService 的实例,是一个代理对象:
在这里插入图片描述

目前,Spring 还没有提供更方便的方式来创建这些代理对象,不过,之后的版本肯定会提供,如果感兴趣的话,可以从 HttpServiceProxyFactorycreateClient方法的源码中看到一些与创建 AOP 代理相似的代码,因此,我推测 Spring 之后可能会增加类似的注解来方便地创建代理对象。

1.4 其他特性

除了上述例子中的简单使用之外,添加了 HttpExchange 的方法还支持各种类型的参数,这一点也与 Spring MVCController 方法类似,方法的返回值也可以是任意自定义的实体类型(就像上面的例子一样),此外,还支持自定义的异常处理。

上面例子中为什么需要 Spring Reactive Web 的依赖
引入了 Spring Reactive Web 的依赖,在创建代理的service对象的时候,使用了其中的 WebClient 类型。这是因为,HTTP Interface 目前只内置了 WebClient 的实现,它属于 Reactive Web 的范畴。Spring 在会在后续版本中推出基于 RestTemplate 的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/346991.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SSM】篇一:初试Spring--Ioc、Bean与容器

文章目录1、Spring2、SpringFramework系统架构3、BeanBean的配置Bean的实例化Bean的生命周期4、依赖注入DIsetter注入和构造器注入依赖自动装配集合注入案例--数据源对象管理加载properties文件5、容器创建容器的两种方式获取bean的三种方式容器类层次结构图1、Spring Spring地…

算法思想 - 搜索算法

本文主要介绍算法中搜索算法的思想&#xff0c;主要包含BFS&#xff0c;DFS。搜索相关题目深度优先搜索和广度优先搜索广泛运用于树和图中&#xff0c;但是它们的应用远远不止如此。BFS广度优先搜索的搜索过程有点像一层一层地进行遍历&#xff0c;每层遍历都以上一层遍历的结果…

【C/C++基础练习题】复习题三,易错点知识点笔记

C复习题知识点记录&#xff1a; 在定义结构体类型时&#xff0c;不可以为成员设置默认值。 在公用一个共用体变量时。系统为其分配存储空间的原则是按成员中占内存空间最大者分配 a ,La, "a", L"a" 字符 长字符 字符串 长字符串 布尔类型只有两个值 fal…

尚医通(十四)Spring Cloud GateWay网关 | 跨域 | 权限认证

目录一、网关基本概念1、API网关介绍2、Spring Cloud Gateway3、Spring Cloud Gateway核心概念二、创建service_gateway模块&#xff08;网关服务&#xff09;1、创建service_gateway模块2、在pom.xml引入依赖3、编写application.properties配置文件4、编写启动类5、前端端口号…

Early Data将在数据应用领域与亚马逊云科技加深合作

数字经济时代&#xff0c;伴随着大数据应用的不断深入&#xff0c;企业对用户及市场发展动向的判断正变得愈加精准。数据资产不再是虚无缥缈的东西&#xff0c;而是可以帮助企业切切实实找到业务增长点&#xff0c;洞悉潜在商机&#xff0c;拥有巨大潜力的“宝藏”。IDC数据显示…

无需登录复制网站文字的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…

基于控制台的购书系统(JAVA基础案例教程-黑马程序员编著-第三章-课后作业)

【案例介绍】 案例描述 伴随互联网的蓬勃发展&#xff0c;网络购书系统作为电子商务的一种形式&#xff0c;正以其高效、低成本的优势逐步成为新兴的经营模式&#xff0c;人们已经不再满足互联网的用途仅仅局限于信息的浏览和发布&#xff0c;更渴望着能够充分享受互联网所带来…

mpls专线与MSTP专线区别在哪里?

首先我们要知道什么是MPLS和MSTP&#xff0c;MPLS&#xff1a;“多协议标签交换机制”。是一种数据传输的机制&#xff0c;可以基于多种不同的3层协议来生成2.5层的标签信息&#xff0c;通过为数据包上分配标签交换替代IP转发&#xff0c;这种标签是短而定长、只具有本地意义的…

代码随想录【Day15】|102. 二叉树的层序遍历、226. 翻转二叉树、101. 对称二叉树

102. 二叉树的层序遍历 题目链接 题目描述&#xff1a; 给你一个二叉树&#xff0c;请你返回其按 层序遍历 得到的节点值。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 难点&#xff1a; 思路&#xff1a; 需要借用一个辅助数据结构即队列来实现…

传输层重要协议之UDP协议和TCP协议详解

更多关于UDP协议和TCP协议请移步官网&#xff1a;https://www.rfc-editor.org/standards#ISUDP标准协议文档-RFC 768TCP标准协议文档-RFC 793UDP协议详解UDP协议的特点&#xff1a;无连接、不可靠传输、面向数据报和全双工。UDP协议报文结构&#xff1a;关于端口号&#xff1a;…

Ubuntu系统为程序创建桌面快捷方式

为了不用每次都要进入命令行启动应用程序&#xff0c;为程序创建快捷方式是一个很方便的方法&#xff0c;尤其是你的程序需要在团队外部使用的时候。桌面创建快捷方式一般使用.desktop为后缀的文件实现&#xff0c;该文件的内容格式基本要素如下&#xff1a;[Desktop Entry] Na…

Git与IDEA强强联合(HTTPS协议连接)

最近在写项目的时候&#xff0c;在台式机和笔记本之间频繁切换&#xff0c;竟然还是用qq传压缩包&#xff0c;我自己都感觉无语&#xff0c;有git这样强大的版本管理工具&#xff0c;我竟然没想起来。然后也没有相关的博文就想来更新一篇。 那么如何使idea和git强强联合呢&…

果实可采摘点论文汇总

文章目录2019基于Mask R-CNN的芒果实例分割及采摘点检测研究与实现2021A mango picking vision algorithm on instance segmentation and key point detection from RGB images in an open orchard2022基于深度学习的多品种鲜食葡萄采摘点定位Method for Identifying Litchi Pi…

webpack(高级)--Prefetch和Preload shimming

webpack Prefetch和Preload webpack v4.6.0 增加了对预获取和预加载的支持 在声明import时 使用下面这些内置指令 来告知浏览器 prefetch(预获取):&#xff1a;将来某些导航下可能需要的资源 preload(预加载)&#xff1a;当前导航下可能需要资源 import(/* webpackChunkName…

Leetcode详解JAVA版

目录1. 两数之和14. 最长公共前缀15. 三数之和18. 四数之和19. 删除链表的倒数第 N 个结点21. 合并两个有序链表28. 找出字符串中第一个匹配项的下标36. 有效的数独42. 接雨水43. 字符串相乘45. 跳跃游戏 II53. 最大子数组和54. 螺旋矩阵55. 跳跃游戏62. 不同路径70. 爬楼梯73.…

Jenkins连接Maven自动化部署构建SpringBoot

目录1.首先下载maven拉取到服务器2.解压maven并进入解压文件修改setting.xml2.拉取jdk18到服务器并解压3.将jdk还有maven移动到jenkins的挂载目录4.进入jenkins容器5.在jenkins的全局配置中配置jdk与maven6.jenkins安装插件 Publish Over SSH7.jenkins服务器创建一个jar包存放目…

ArcGIS API for JavaScript 4.15系列(6)——Dojo中的事件绑定

1、前言 在Web界面中&#xff0c;用户点击按钮、选择下拉选项、移动鼠标都涉及到dom元素的事件机制。下面就来介绍一下Dojo中的事件绑定操作。 2、dojo/on模块绑定事件 我们就从最简单的按钮click事件入手&#xff0c;Dojo中的dojo/on模块可以实现dom元素的事件绑定&#xf…

高性能办公娱乐迷你主机——Maxtang大唐AMD5600U

今天给大家介绍一款AMD5600U迷你主机&#xff0c;说起这款处理器大家应该并不陌生&#xff0c;像联想小新、YOGA以及ThinkBook等很多款用的都是这个型号&#xff0c;不过笔记本的价格基本都在3999-4999这个价位区间&#xff0c;同样的处理器&#xff0c;笔记本卖那么贵&#xf…

内网渗透(二十八)之Windows协议认证和密码抓取-Windows RDP凭证的抓取和密码破解

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

帮公司面试了一个30岁培训班出来的程序员,没啥工作经验...

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…