共计 3079 个字符,预计需要花费 8 分钟才能阅读完成。
起源:https://juejin.cn/post/717327…
近期,Spring 6 的第一个 GA 版本公布了,其中带来了一个新的个性——HTTP Interface。这个新个性,能够让开发者将 HTTP 服务,定义成一个蕴含特定注解标记的办法的 Java 接口,而后通过对接口办法的调用,实现 HTTP 申请。看起来很像应用 Feign 来实现近程服务调用,上面咱们参考官网文档来实现一个 Demo。
实现一个 Demo
首先创立一个简略的 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
地址获取到一个蕴含十个用户信息的用户列表。
上面咱们新建一个 Spring Boot 工程。Spring Boot 根底就不介绍了,举荐看这个收费教程:
https://github.com/javastacks/spring-boot-best-practice
这里须要留神,Spring Boot 的版本至多须要是 3.0.0,这样它以来的 Spring Framework 版本才是 6.0 的版本,才可能蕴含 HTTP Interface 个性,另外,Spring Framework 6.0 和 Spring Boot 3.0 开始反对的 Java 版本最低是 17,因而,须要抉择至多是 17 的 Java 版本。
另外,须要依赖 Spring Web 和 Spring Reactive Web 依赖,起因下文中会提到。
创立好新的 Spring Boot 工程后,首先须要定义一个 HTTP Interface 接口。最简略的定义如下即可:
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
以上是一个最简略的示例,上面咱们看看其中的一些细节。
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 {};}
在下面的例子中,咱们只指定了申请的资源门路。
UserApiService 实例的创立
在下面例子中,咱们定义的 HTTP Interface 接口是 UserApiService,在测试方法中,咱们通过 HttpServiceProxyFactory 创立了 UserApiService 的实例,这是参考了 Spring 的官网文档的写法。
你也能够将创立的过程写到一个 @Bean 办法中,从而能够将创立好的实例注入到其余的组件中。
咱们再定义 UserApiService 的时候,只是申明了一个接口,那具体的申请操作是怎么收回的呢,咱们能够通过 DEBUG 模式看得出来,这里创立的 UserApiService 的实例,是一个代理对象:
目前,Spring 还没有提供更不便的形式来创立这些代理对象,不过,之后的版本必定会提供,如果你感兴趣的话,能够从 HttpServiceProxyFactory 的 createClient
办法的源码中看到一些与创立 AOP 代理类似的代码,因而,我揣测 Spring 之后可能会减少相似的注解来不便地创立代理对象。
其余个性
除了上述例子中的简略应用之外,增加了 HttpExchange 的办法还反对各种类型的参数,这一点也与 Spring MVC 的 Controller 办法相似,办法的返回值也能够是任意自定义的实体类型(就像下面的例子一样),此外,还反对自定义的异样解决。
为什么须要 Spring Reactive Web 的依赖
上文中创立工程的时候,引入了 Spring Reactive Web 的依赖,在创立代理的 service 对象的时候,应用了其中的 WebClient 类型。这是因为,HTTP Interface 目前只内置了 WebClient 的实现,它属于 Reactive Web 的领域。Spring 在会在后续版本中推出基于 RestTemplate 的实现。
总结
本文带你对 HTTP Interface 个性进行了简略的理解,我之后会深入研究这个个性,也会追踪后续版本中的改良并与你分享,欢送点赞加关注。
近期热文举荐:
1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)
2. 劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!