還在用OpenFeign?來試試SpringBoot3 中的這個新玩意!
還在用OpenFeign?來試試SpringBoot3 中的這個新玩意!
年過完啦,松哥也已經搬磚搬了三天了。
疫情放開後,今年這個年格外的輕鬆愜意,心中一種特別壓抑的東西被除去了,新聞中看到各地遊人如織、西安大唐不夜城遊人摩肩接踵,真的好像回到了2019 年一樣,朋友圈中也都是喜氣洋洋,生活還是很美好的。
好久沒發技術文章了,最近回到工作地,晚上有空又可以碼碼技術了,今天我們就來聊一個Spring Boot3 中的新鮮玩意,聲明式HTTP 調用。
1. 由來
Spring Boot3 去年底就已經正式發布,我也嚐了一把鮮,最近有空會和小伙伴們慢慢聊聊Spring Boot3 都給我們帶來了哪些新東西。
今天我們就先來看看聲明式HTTP 接口。
用過Spring Cloud 的小伙伴都知道,在Spring Cloud 家族中,負責進程間通信的,我們可以使用RestTemplate 或者OpenFeign(當然也有其他方式如基於消息中間件的消息驅動的微服務或者基於gRPC 的調用等)。
RestTemplate 我們可以將之當作一個普普通通的HTTP 調用工具來對待,區別於其他的HTTP 客戶端,RestTemplate 用來調用RESTful 風格的接口特別方便。
不過,比RestTemplate 更加方便的是OpenFeign,通過接口聲明就可以實現遠程調用,這些的具體用法松哥在之前的視頻中講過,這裡就不再贅述了。
以前我們想要用聲明式HTTP 調用,需要通過OpenFeign 來實現,這個需要第三方的依賴,從Spring6 開始(Spring Boot3),Spring 自己提供了類似的功能通過 @HttpExchange 註解也能方便的實現聲明式HTTP 調用。以後跨服務調用又多了一個選擇。
2. 使用
接下來松哥通過一個案例來和小伙伴們演示一下 @HttpExchange 註解的具體玩法。
首先我們先創建一個普通的名為server 的Spring Boot 項目,這個普通的Spring Boot 項目中只需要提供一個簡單的測試接口即可,如下:
@RestController
public class HelloController {
@GetMapping("/server/hello")
public String hello(String name){
return "hello " + name;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
這個對大家來說應該是沒什麼難度的,我就不多說了。
現在假設我有另外一個服務名為client,我想在client 中調用server 中提供的這個接口。
首先我们来创建 client 这个项目,大家注意,创建的时候我们不仅需要添加 Web 依赖,还需要 Reactive Web,因为这个 @HttpExchange 底层基于 WebClient,而 WebClient 则是 Reactive Web 提供的:
创建完成后,接下来我们就可以声明 Http 接口了:
@HttpExchange("/server")
public interface ToDoService {
@GetExchange("/hello")
String hello(@RequestParam String name);
}
- 1.
- 2.
- 3.
- 4.
- 5.
这些用法跟我们在 SpringMVC 中常用的 @RequestMapping 和 @GetMapping 等特别类似:
- @HttpExchange 类似于 @RequestMapping,可以将之放在类上,起到一个请求窄化的作用,也可以放在方法上,放在方法上我们可以通过 method 属性来指定具体的请求方法,这个也跟 @RequestMapping 类似:@HttpExchange(value = "/server",method = "GET")。
- @GetExchange 类似于 @GetMapping,这个就不再赘述了,其他类似的注解还有 @DeleteExchange、@PatchExchange、@PostExchange、@PutExchange 等。
- 另外需要注意的是请求方法的参数需要加上@RequestParam 注解,这一点和 OpenFeign 比较类似。
接口声明好之后还没完,我们还需要配置一下才能使用。如下:
@Configuration
public class WebConfig {
@Bean
WebClient webClient(){
return WebClient.builder()
.baseUrl("http://localhost:8080")
.build();
}
@Bean
ToDoService toDoService(){
HttpServiceProxyFactory httpServiceProxyFactory =
HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient()))
.build();
return httpServiceProxyFactory.createClient(ToDoService.class);
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
这个配置主要是两方面:
- @HttpExchange 是基于 WebClient 的,所以我们首先需要配置 WebClient,配置 WebClient 的时候,也顺便配置了请求的具体地址(因为在 @HttpExchange
- 由于我们前面提供的 ToDoService 是一个接口,所以我们还需要提供一个该接口的实现类,当然这个配置完全是套路化模版化的,这块就没啥好说了。
全部配置完成后,接下来我们就可以在任何需要的地方,直接注入 ToDoService 的实例去使用了,举一个简单的例子小伙伴们参考下:
@SpringBootTest
class ClientApplicationTests {
@Autowired
ToDoService toDoService;
@Test
void contextLoads(){
String hello = toDoService.hello("javaboy");
System.out.println("hello = " + hello);
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
好啦,一个简单的例子,小伙伴们不妨体验下。
以后,不用 OpenFeign 也能实现声明式服务调用啦~