且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Spring Boot WebClient.Builder bean在传统servlet多线程应用程序中的用法

更新时间:2023-09-09 17:47:52

您是对的,WebClient.Builder不是线程安全的.

You're right, WebClient.Builder is not thread-safe.

Spring Boot正在将WebClient.Builder创建为原型bean,因此您将为每个注入点获得一个新实例.在您看来,您的组件在我看来似乎有些奇怪.

Spring Boot is creating WebClient.Builder as a prototype bean, so you'll get a new instance for each injection point. In your case, your component seems a bit strange in my opinion.

它应该看起来像这样:

@Service
public class MyService{

    private final WebClient webClient;

    public MyService(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("http://localhost:8000").build();
    }

    public VenueDTO serviceMethod(){
        VenueDTO venueDTO = webClient.get().uri("/api/venue/{id}", bodDTO.getBusinessOutletId()).
                retrieve().bodyToMono(VenueDTO.class).
                blockOptional(Duration.ofMillis(1000)).
                orElseThrow(() -> new BadRequestException(venueNotFound));
                return VenueDTO;
    }
}

现在我想这是一个代码段,您的应用程序可能有不同的约束.

Now I guess this is a code snippet and your application may have different constraints.

如果您的应用程序需要经常更改基本URL,那么我认为您应该停止在构建器上对其进行配置,并按照问题中的说明传递完整的URL.如果您的应用程序有其他需求(用于身份验证的自定义标头等),那么您也可以在构建器上或根据每个请求进行此操作.

If your application needs to change the base URL often, then I think you should stop configuring it on the builder and pass the full URL as mentioned in your question. If your application has other needs (custom headers for authentication, etc), then you can also do that on the builder or on a per request basis.

通常,您应该尝试为每个组件构建一个WebClient实例,因为为每个请求重新创建它都是非常浪费的.

In general, you should try and build a single WebClient instance per component, as recreating it for each request is quite wasteful.

如果您的应用程序具有非常特定的约束,并且确实需要创建其他实例,那么您始终可以调用webClientBuilder.clone()并获取一个可以更改的构建器新实例,而不会出现线程安全问题.

In case your application has very specific constraints and really needs to create different instances, then you can always call webClientBuilder.clone() and get a new instance of the builder that you can mutate, without the thread safety issues.