【发布时间】:2019-06-05 18:14:01
【问题描述】:
我希望有一个 http 客户端从 Spring Boot not reactive 应用程序中调用其他微服务。由于 RestTemplate 将被弃用,我尝试使用 WebClient.Builder 和 WebClient。虽然我不确定线程安全。这里的例子:
@Service
public class MyService{
@Autowired
WebClient.Builder webClientBuilder;
public VenueDTO serviceMethod(){
//!!! This is not thread safe !!!
WebClient webClient = webClientBuilder.baseUrl("http://localhost:8000").build();
VenueDTO venueDTO = webClient.get().uri("/api/venue/{id}", bodDTO.getBusinessOutletId()).
retrieve().bodyToMono(VenueDTO.class).
blockOptional(Duration.ofMillis(1000)).
orElseThrow(() -> new BadRequestException(venueNotFound));
return VenueDTO;
}
}
本示例中的serviceMethod() 将从几个线程中调用,webClientBuilder 是单个bean 实例。 WebClient.Builder 类包含状态:baseUrl,这似乎不是线程安全的,因为很少有线程可以同时调用此状态更新。同时,WebClient 本身似乎是线程安全的,正如Right way to use Spring WebClient in multi-thread environment 的回答中提到的那样
我应该使用https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-webclient.html 中提到的 WebClient.Builder bean
Spring Boot 为您创建和预配置一个 WebClient.Builder;它 强烈建议将其注入您的组件中并用于 创建 WebClient 实例。
我看到的解决方法之一是创建 WebClient 而不将任何状态传递给构建器,而不是:
WebClient webClient = webClientBuilder.baseUrl("http://localhost:8000").build();
我会的:
WebClient webClient = webClientBuilder.build();
并在 uri 方法调用中传递带有协议和端口的完整 url:
webClient.get().uri("full url here", MyDTO.class)
在我的情况下使用它的正确方法是什么?
【问题讨论】:
标签: spring spring-boot spring-webflux