Java精選面試題(微信小程序):5000+道面試題和選擇題,真實面經,簡歷模版,包含Java基礎、并發、JVM、線程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架構設計、大廠真題等,在線隨時刷題!
近期,Spring 6 的第一個 GA 版本發布了,其中帶來了一個新的特性——HTTP Interface。這個新特性,可以讓開發者將 HTTP 服務,定義成一個包含特定注解標記的方法的 Java 接口,然后通過對接口方法的調用,完成 HTTP 請求。看起來很像使用 Feign 來完成遠程服務調用,這可能是 Spring “拋棄” feign 等 http 調用的一種趨勢,Spring 要規范和簡化這一塊的實現了,讓開發者更關注聚集于業務。下面我們參考官方文檔來完成一個 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 list() { return IntStream.rangeClosed(1, 10) .mapToObj(i -> new User(i, "User" + i)) .collect(Collectors.toList()); }確保啟動服務之后,能夠從http://localhost:8080/users地址獲取到一個包含十個用戶信息的用戶列表。
下面我們新建一個 Spring Boot 工程。
![]()
這里需要注意,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 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 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 特性進行了簡單的了解,我之后會深入研究這個特性,也會追蹤后續版本中的改進并與你分享,歡迎點贊加關注。
來源:https://juejin.cn/post/7173271507047546893
公眾號“Java精選”所發表內容注明來源的,版權歸原出處所有(無法查證版權的或者未注明出處的均來自網絡,系轉載,轉載的目的在于傳遞更多信息,版權屬于原作者。如有侵權,請聯系,筆者會第一時間刪除處理!
最近有很多人問,有沒有讀者交流群!加入方式很簡單,公眾號Java精選,回復“加群”,即可入群!
文章有幫助的話,點在看,轉發吧!
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.