取代OpenFeign:Spring Framework 6全新声明式客户端@HttpExchange

news2024/12/23 19:52:15

在这里插入图片描述

本文已被https://yourbatman.cn收录;女娲Knife-Initializr工程可公开访问啦;程序员专用网盘https://wangpan.yourbatman.cn;技术专栏源代码大本营:https://github.com/yourbatman/tech-column-learning;公号后台回复“专栏列表”获取全部小而美的原创技术专栏

你好,我是YourBatman:一个俗人,贪财好色。

TitleLink
所属专栏[YourBatman]-Spring技术栈
源代码https://github.com/yourbatman/FXP-java-ee
程序员专用网盘公益上线啦,注册送1G超小容量,帮你实践做减法https://wangpan.yourbatman.cn
Java开发软件包(Mac)https://wangpan.yourbatman.cn/s/rEH0 提取码:javakit
女娲工程http://152.136.106.14:8761
版本约定[Mac OS 13.1],[IDEA 2022.3.1],[Spring Boot 3.0.x]

📚前言

Http是最常见的请求协议,每种编程语言都可发送Http请求。Java作为经典编程语言之一,发送Http请求的客户端更是不少,自己的内置的就有java.net.HttpURLConnection以及Java 11以后的java.net.http.HttpClient。在Java 11之前,HttpURLConnection很难用,因此市场上百花齐放出现了不少优秀的开源作品,典型代表为:

  • Apache HttpClient(现最新为Http Component 5.x)
  • OkHttp(现最新为OkHttp 4.x)

作为老牌的Apache HttpClient凭借着各种优秀特征,似乎已成为了事实的标准;后起之秀OkHttp不带历史包袱的轻装上路,有着低网络延迟、更优秀的连接池性能,亦是一股不可轻视的力量。

Spring不到万不得已之时,一般不会自己重复造轮子。在Http客户端这块一样借力打力,提供Http统一调用方式RestTemplate,屏蔽了细节,规范了开发者的使用,简化了开发门槛。

PS:RestTemplate的底层实现依旧是Apache HttpClient、OkHttp、HttpURLConnection之一

以上,都还是编程式Http客户端。随着Spring Boot的普及,Spring Cloud的出现,声明式编码变得越来越主流,因为声明式/面向元数据编码效率远高于编程式编码效率。因此,Feign出现了,迅速成为了主流。

今年,随着划时代版本Spring Framework 6、Spring Boot 3、Spring Cloud 2022.0.0的发布,Spring团队自建了一套声明式Http客户端:@HttpExchange,目标直指OpenFeign。

✍正文

全新的声明式Http客户端由Spring Framework 6提供定义,Spring Boot 3提供实现,Spring Cloud 2022负责发扬光大。今天我们就来体验一把

🌈介绍一个免费的、在线的Rest Http服务

由于我们需要一个提供Http Server来提供接口服务,为此先给你介绍一个免费的、24h在线的Rest Http服务,省去我们自己搭建的麻烦。

地址:jsonplaceholder.typicode.com
在这里插入图片描述
每月提供近20亿的请求,关键还是免费的、可公开访问的,好用得不要不要
在这里插入图片描述
发一个简单的Http请求,就能获取到数据。URL遵循Rest规范:
在这里插入图片描述
不挑Http或者Https,比如使用浏览器访问这个URL得到的结果也是一样的:
在这里插入图片描述
它提供多个Resources资源(以及多种Routes)供以访问,对这些资源进行增删改查的操作,你想要的绝大部分都能满足你。当然,若你需要mock data是符合自己的数据结构、业务逻辑的,可基于此项目做简单的修改即可,良心项目啊。具体详情自行去官方体验:https://jsonplaceholder.typicode.com

🌈全新声明式Http客户端@HttpExchange

环境声明:Spring Boot 3.0.x

本文选用”albums“资源进行测试:https://jsonplaceholder.typicode.com/albums的请求结果结构如下:
在这里插入图片描述

🚀Feign代码示例

略!Feign的使用,相信大家再熟悉不过了,笔者这里就不费周章。

🚀@HttpExchange代码示例

🙅🏻‍♀️按照albums的返回数据结构,写Java Bean:

/**
 * 在此处添加备注信息
 *
 * @author YourBatman
 * @since 0.0.1
 */
@Builder
@Getter
public class AlbumsReq {

    @NotNull
    @Positive
    private Long userId;
    @NotBlank
    private String title;

}


/**
 * 在此处添加备注信息
 *
 * @author YourBatman
 * @since 0.0.1
 */
@Setter
@ToString
public class AlbumsResp {

    private Long id;
    private Long userId;
    private String title;

}

顺带科普一个编码规范:请求体Req中get方法是必须的,set方法可选;响应体Resp中set方法是必须的,get方法可选;二者都需遵循Java Bean规范! 粗暴的做法是不管需求如何,get/set一把梭,可行,但作为程序员的你应该知道原由,理解要义。

🙅🏻‍♀️导入webflux包
此声明式客户端又Spring Framework 6提供,但由于其并未提供实现。Spring Boot 3为此提供了基于Reactive的Web实现,因此需要导入webflux包:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

🙅🏻‍♀️编写Http客户端申明式接口

/**
 * 在此处添加备注信息
 *
 * @author YourBatman
 * @since 0.0.1
 */
@HttpExchange("/albums")
public interface AlbumsClient {

    @GetExchange
    List<AlbumsResp> getAll();

    @GetExchange("/{id}")
    AlbumsResp getById(@PathVariable Long id);

    @PostExchange
    AlbumsResp add(@RequestBody @Valid AlbumsReq req);

}

🙅🏻‍♀️Client配置类

/**
 * 在此处添加备注信息
 *
 * @author YourBatman
 * @since 0.0.1
 */
@Configuration(proxyBeanMethods = false)
public class WebClientConfiguration {

    @Bean
    public AlbumsClient albumsClient(WebClient.Builder webClientBuilder) {
        WebClient webClient = webClientBuilder.baseUrl("https://jsonplaceholder.typicode.com").build();
        return HttpServiceProxyFactory.builder().clientAdapter(WebClientAdapter.forClient(webClient)) //
                .build().createClient(AlbumsClient.class);
    }

}

🙅🏻‍♀️书写测试用例代码

@SpringBootTest
class ApplicationTests {

    @Autowired
    private AlbumsClient albumsClient;

    @Test
    void contextLoads() {
        System.out.println("getAll size:" + albumsClient.getAll().size());

        System.out.println("getById 1:" + albumsClient.getById(1L));

        // 创建一个
        Object addedResp = albumsClient.add(AlbumsReq.builder().userId(1L).title("diy add...").build());
        System.out.println("创建的allAlbums对象为:" + addedResp + ",现在总数为:" + albumsClient.getAll().size());
    }

}

🙅🏻‍♀️运行测试代码,控制台输出:

getAll size:100
getById 1:AlbumsResp(id=1, userId=1, title=quidem molestiae enim)
创建的allAlbums对象为:AlbumsResp(id=101, userId=1, title=diy add...),现在总数为:100

完美!

小细节:创建的时候并未制定id,发现id是自增的(id=101)。但这并不会保存在typicode.com的远端服务器了,不会引起总条数的变化

🚀@HttpExchange声明式客户端简析

@HttpExchange是Spring Framework 6新提供的声明式Http客户端,客户端的要素由注解的属性 + 方法签名来定义。先来看看这个注解:

/**
* Since: 6.0
*/
@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 {};
}

@RequestMapping参照对比:

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

	String name() default "";
	@AliasFor("path")
	String[] value() default {};
	@AliasFor("value")
	String[] path() default {};
	RequestMethod[] method() default {};
	String[] params() default {};
	String[] headers() default {};
	String[] consumes() default {};
	String[] produces() default {};

}

不说一毛一样,也是基本一样。@HttpExchange注解可以标注在类上和方法上,最终的URL组合起来生效。大家都是使用过Feign、使用过Spring MVC的,这就不用过多介绍了。

@RequestMapping一样,@HttpExchange也有其派生注解:

  • @GetExchange:GET请求。类似于于@GetMapping
  • @PostExchange:Post请求。类似于于@PostMapping
  • @PutExchange:Put请求。类似于于@PutMapping
  • @DeleteExchange:Delete请求。类似于于@DeleteMapping
  • @PatchExchange:Patch请求。类似于于@PatchMapping

🚀@HttpExchange声明式客户端前景展望

通过interface这种声明式使用起来比RestTemplate,或者WebClient要简单很多,大大简化了开发步骤,对开发者更加友好。

最新发布的Spirng Cloud 2022.0.0里描述得很明白:停止对OpenFeign的特征支持。言外之意:OpenFeign即将被Spring Cloud“淘汰”,接棒的那必然是@HttpExchange喽。所以在可预见的将来,前景一片大好。
在这里插入图片描述
但是,笔者认为它还不够成熟,主要有两点:

  1. 还不能支持Spring-Web的注解(@RequestMapping体系),若能支持个人觉得会更为方便
  2. 目前还只有WebClient一套实现(由Spring Boot提供实现),而它属于Reactive Web体系,也就是必须引入webFlux相关技术,而webFlux在做业务开发时优势不明显,并非主流
    1. 因为若WebClient能从Reactive Web里剥离出来,笔者觉得就好很多了

🍞总结

谁能想到,OpenFeign竟然都快被淘汰了,Spring的大船滚滚向前,引领着整个潮流,逐渐暴露出了野心,或者说感受到了危机。

先抄袭,再超越,Spring做到了。隐藏在全新的声明式客户端背后,其实还有Spring Framework 6背后对Web Mapping体系的重构,细心的你或许已有所发现。这些话题、新发现,留予笔者和你后续接着聊。

推荐阅读

  • IntelliJ IDEA 2022.3正式发布,配置云同步&支持Redis好用到炸
  • Spring Framework 6正式发布,携JDK 17&Jakarta EE开启新篇章
  • IntelliJ IDEA 2022.2正式发布,支持Spring Boot 3和Spring 6
  • JVM除了HotSpot,你还知道哪些?
  • YourBatman用趣味代码雨祝你:端午安康
  • 逐渐碎片化的Java生态圈:Oracle JDK、OpenJDK、阿里Dragonwell、华为毕昇

在这里插入图片描述

我是YourBatman:前25年不会写Hallo World、早已毕业的大龄程序员。高中时期《梦幻西游》骨灰玩家,网瘾失足、清考、延期毕业、房产中介、保险销售、送外卖…是我不可抹灭的黑标签

  • 🎓2013.07 清考、毕业答辩3次未通过、延期毕业
  • 🏷2013.08-2014.07 宁夏中介公司卖二手房1年,毕业后第1份工作
  • ️️🏷2014.07-2015.05 荆州/武汉,泰康人寿卖保险3月、饿了么送外卖2月,还有炸鸡排、直销等第2345份工作
  • 🏷2015.08 开始从事Java开发,闯过外包,呆过大厂!擅长抽象思维,任基础架构团队负责人
  • 🏷2021.08 因“双减政策”失业!历经9面,终获美团外卖L8的offer
  • 🙅🏻‍♀️Java架构师、Spring开源贡献者、CSDN博客之星年度Top 10、领域建模专家、写作大赛1/2届评委
  • 📚高质量代码、规范践行者;DDD领域驱动深度实践;即将出版书籍《Spring奇淫巧技》

在这里插入图片描述

序号专栏名称简介
01[YourBatman]-程序人生程序人生,人生程序
02[YourBatman]-资讯/新特性IDEA、JDK、Spring技术栈…新特性
03[YourBatman]-IntelliJ IDEA熟练使用IDEA就相当拥有物理外挂,助你高效编码
04[YourBatman]-Bean Validation熟练掌握数据校验,减少90%的垃圾代码
05[YourBatman]-日期时间帮你解决JDK Date、JSR 310日期/其实 的一切问题
06[YourBatman]-Spring类型转换Spring类型转换-框架设计的基石
07[YourBatman]-Spring staticstatic关键字在Spring里的应用
08[YourBatman]-Cors跨域关于跨域请求问题,本专栏足矣
09[YourBatman]-JacksonAlmost Maybe是最好的Jackson专栏
10[YourBatman]-Spring配置类专讲@Configuration配置类,你懂的
11[YourBatman]-Spring技术栈暂无所属小分类的,Spring技术栈大分类
12[YourBatman]-JDK暂无所属小分类的,JDK技术栈大分类
13[YourBatman]-ServletServlet规范、Web相关内容专题
14[YourBatman]-Java EE从Java EE到Jakarta EE,30年弹指一挥间
15[YourBatman]-工具/提效开发工具、软件工具,目标是提效
16[YourBatman]-Spring技术栈新特性 Spring Framework、Spring Boot、Spring Cloud、Spring其它技术
17[YourBatman]-基本功 每个Javaer,都需要有扎实的基本功
99源代码库大多数专栏均配有源代码,都在这里
  • 源代码库地址:https://github.com/yourbatman/tech-column-learning
  • CSDN主页:https://blog.csdn.net/f641385712
  • 掘金主页:https://juejin.cn/user/430664289367192
  • 博客园主页:https://www.cnblogs.com/yourbatman
  • 个人博客主页:https://yourbatman.cn
  • 个人网盘主页:https://wangpan.yourbatman.cn

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

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

相关文章

【几种可调动对象,Function和bind;线程的调动方式举例】

1.可调动对象的调动方式 方法 1、函数指针调动 方法2 、类类型的括号的重载 调动可调动对象 #include<iostream> #include<functional> using namespace std; struct Foo {void operator()(int x){cout<<"Foo operator "<<x<<endl;}…

CSS3【定位的基本使用[静态定位\相对定位\绝对定位]、子绝父相、固定定位、元素的层级关系】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录一、定位1.1定位的基本介绍1.1.1 网页常见布局方式1.1.2 定位的常见应用场景1.2 定位的基本使用1.2.1 定位初体验1.2.2 使用定位的步骤1.2.3 静态定位1.2.4 小结1.2.…

使用 Docker Hub 完美地存储 Helm 图表实战

使用 Docker Hub 完美地存储 Helm 图表实战 Helm 是 Kubernetes 的包管理器。它是一个开源容器编排系统。它通过提供一种简单的方法来定义、安装和升级复杂的 Kubernetes 应用程序&#xff0c;帮助您管理 Kubernetes 应用程序。 使用 Helm&#xff0c;您可以将您的应用程序打包…

git教程

教程目录Git 教程Git 与 SVN 区别Git 与 SVN 区别点&#xff1a;Git 安装配置Linux 平台上安装Debian/UbuntuCentos/RedHatWindows 平台上安装Mac 平台上安装Git 配置用户信息文本编辑器##差异分析工具查看配置信息Git 工作流程Git 工作区、暂存区和版本库基本概念Git 创建仓库…

semargl 软件使用方法简介

文章目录前言一、semargl 软件使用简介1.semargl 软件简介2.准备演示软件操作所需的数据3.使用 semargl 获取频谱关系4.使用 semargl 获取特定频率模式的空间分布5.使用 semargl 获取自旋波的色散关系二、笔记05第三节内容的补充1.优化多进程读取磁化数据文件的代码2.新增获取特…

【JavaSE】 常用类(447~515)

String 447.常用类-每天一考 1.画图说明线程的生命周期&#xff0c;以及各状态切换使用到的方法等 状态&#xff0c;方法 2.同步代码块中涉及到同步监视器和共享数据&#xff0c;谈谈你对同步监视器和共享数据的理解&#xff0c;以及注意点。 synchronized(同步监视器){//操…

Python手势识别与追踪

程序示例精选 Python手势识别与追踪 如需安装运行环境或远程调试&#xff0c;见文章底部微信名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<Python手势识别与追踪>>编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 应…

【日常】圣诞节、颜色⛄

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 关于圣诞节&#x1f384;&#xff0c;大家想到什么颜色&#xff1f;⛄&#x1f98c;&#x1f381;&#x1f385;&#x1f525; demo online - https://codepen.io/adamlindqvist/pen/EaPeJg html <!-- Christ…

详细介绍关于自定义类型:结构体、枚举、联合【c语言】

文章目录结构体结构体的声名特殊的声明结构成员的类型结构的自引用结构体变量的定义和初始化结构体内存对齐修改默认对齐数结构体变量访问成员结构体传参结构体实现位段&#xff08;位段的填充&可移植性&#xff09;位段的内存分配位段的跨平台问题枚举枚举类型的定义枚举的…

【Linux】用户与用户组操作_补

文章目录一.用户1.1 用户与用户组概念1.2 与用户管理相关的系统文件1.3 查看用户组1.3.1用户组密码配置文件&#xff0f;etc&#xff0f;gshadow1.4用户管理创建用户修改用户添加密码一.用户 1.1 用户与用户组概念 用户和用户组的对应关系有&#xff1a;一对一、一对多、多对一…

【C语言进阶】指针练习题

写在前面 这是指有关指针的小题 正文 练习一 int main() {int a[5][5];int (*p)[4];pa;printf("%p,%d", &p[4][2]-&a[4][2], &p[4][2]-&a[4][2] );return 0; } 解析&#xff1a; a[4][2]为如图粉色部分&#xff0c;p[4][2]为如图蓝色部分。a的…

【ROS通信机制实战练习】通过话题发布实现turtlesim小乌龟圆周运动

本节记录下使用ROS中的话题机制&#xff0c;实现turtlesim中小乌龟的圆周运动。 如果想通过话题通信机制&#xff0c;实现小乌龟的圆周运动&#xff0c;需要首先明确小乌龟的运动情况&#xff0c;以及所涉及的指挥运动的参数&#xff0c;这里需要首先手动发布一个turtlesim的节…

springboot整合mybatis代码快速生成

特别说明&#xff1a;本次项目整合基于idea进行的&#xff0c;如果使用Eclipse可能操作会略有不同&#xff0c;不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

String 字符串

String 基本介绍 String 应该是 Java 中最常用的一个对象&#xff0c;他不是八种基本数据类型的其中之一&#xff0c;但是随便翻了一下项目代码&#xff0c;用 String 定义的变量超过百分之八十。 public final class Stringimplements java.io.Serializable, Comparable<…

VUE3-计算属性和监听器《五》

目录 一&#xff0c;计算属性 二&#xff0c;监听器 在vue3种&#xff0c;当界面上需要处理一些数据的时候&#xff0c;可以通过计算属性和监听器处理&#xff0c;他们都是对一个属性进行操作的&#xff0c;然后返回数据。 他们的区别是&#xff0c;计算属性&#xff0c;是通…

20221226英语学习

今日短文 When we are shown two options, our eyes tend to flick from one to the other and back again several times as we deliberate on the pros and cons of each. Researchers at Johns Hopkins University in the US have found that the speed with which our ey…

Hbase是什么?

Hadoop Database简介表结构数据只能读不能改>生成新版本总结简介 永远的百度百科 HBase是一个分布式的、面向列的开源数据库&#xff0c;一个结构化数据的分布式存储系统”。 HBase不同于一般的关系数据库&#xff0c;它是一个适合于非结构化数据存储的数据库。另一个不同的…

过年首秀 - 用python写一个自动生成春联的软件并打包exe

前言 哈喽啊&#xff0c;我亲爱的铁铁们&#xff0c;I am back &#xff01;&#xff01; 别管&#xff0c;我也是阳过的人了&#xff0c;这么久都没有更新&#xff0c;今天就带来个小玩意吧 这不是过完圣诞就要过年了吗 这不得准备准备&#xff0c;春节的表演&#xff1f;…

excel数据处理技巧:组合函数统计产品批号

这是一个看似普通的编号问题&#xff0c;可竟然动用了TEXT和SUMPRODUCT两个重量级的函数共同出手才得以解决。以往遇到的编号问题&#xff0c;大多数都是COUNTIF的拿手好戏&#xff0c;但是今天这个问题COUNTIF完全插不上手&#xff0c;来看看模拟的数据吧。 如图所示&#xff…

「 理财与风险控制|养老系列」你想象中的高端养老社区是什么样?

本文主要介绍为什么养老规划需要考虑养老社区的部分&#xff0c;当前市场上养老社区的各种现状&#xff0c;养老社区从各个角度分类&#xff0c;选择养老社区需要关注的要素以及保险保单能够提供的养老权益是怎样的 文章目录01 为什么要关注养老社区&#xff1f;02 为什么关注高…