來源:https://juejin.cn/post/7173271507047546893

近期,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開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544168.html
標籤:Java
