ServiceImpl 构造函数中的 Spring Boot WebClient Builder 初始化

Kam*_*arg 3 java spring-boot spring-webflux spring-webclient

我正在尝试遵循使用 WebClient Builder 自动装配 Webclient 的最佳实践,但很少混淆。

这是我的主要应用程序,我正在其中生成一个 Webclient Builder 并在我的一个服务类中自动装配它

 @SpringBootApplication
    public class MyApplication {
        @Bean
        public WebClient.Builder getWebClientBuilder() {
            return WebClient.builder();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }}


ServiceImpl Class

    public class MyServiceImpl implements MyService {
        private static final String API_MIME_TYPE = "application/json";
        private static final String API_BASE_URL = "http://localhost:8080";
        private static final String USER_AGENT = "Spring 5 WebClient";
        private static final Logger logger = LoggerFactory.getLogger(MyServiceImpl.class);
    
        @Autowired
        private WebClient.Builder webClientBuilder;
    
        @Override
        public Mono<Issue> createIssue(Fields field) {
            return webClientBuilder.build()
                    .post()
                    .uri("/rest/api/")
                    .body(Mono.just(field), Fields.class)
                    .retrieve()
                    .bodyToMono(Issue.class);
        }}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 BaseURl、DefaultHeader 等构建 webClientBuilder。我尝试在 MyServiceImpl Constructer 中对其进行初始化,但不确定它是否正确。

public MyServiceImpl() {
            this.webClientBuilder
                    .baseUrl(API_BASE_URL).defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
                    .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
                    .build();
        } 
Run Code Online (Sandbox Code Playgroud)

我这样做是正确的还是有更好的方法来做到这一点。

目前我有 2 个 ServiceImpls 来调用不同的 API,这就是我试图在服务本身中设置“baseurl”和其他默认值的原因。

请帮忙。TIA

rae*_*tio 5

通常,您的方法是这样的:

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@Configuration
public class MyApplicationConfiguration {
    
    @Bean
    public WebClient myWebClient(WebClient.Builder webClientBuilder) {
        return webClientBuilder
                .baseUrl(API_BASE_URL)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
                .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
                .build();
    }
}

@Service
public class MySericeImpl implements MyService {

    @Autowired
    private WebClient myWebClient;

    @Override
    public Mono<Issue> createIssue(Fields field) {
        return myWebClient
                .post()
                .uri("/rest/api/")
                .body(Mono.just(field), Fields.class)
                .retrieve()
                .bodyToMono(Issue.class);
    }
 }
Run Code Online (Sandbox Code Playgroud)

要记住的关键WebClient.Builder是已经为您预先配置好并且已经创建了 Bean。所以你只需要自动装配它,调整配置并构建最终的WebClient.

也可以使用另一种方法来配置它。有 3 种主要的自定义方法WebClient。有关更多详细信息,请参阅官方文档https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-webclient


编辑以使用更多 API - 配置多个 WebClient 并在适当的服务类中自动装配它们。

@Configuration
public class MyApplicationConfiguration {
    
    @Bean
    public WebClient myWebClientForApi1(WebClient.Builder webClientBuilder) {
        return webClientBuilder
                .clone()
                .baseUrl(API_1_BASE_URL)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
                .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
                .build();
    }

    @Bean
    public WebClient myWebClientForApi2(WebClient.Builder webClientBuilder) {
        return webClientBuilder
                .clone()
                .baseUrl(API_2_BASE_URL)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 没问题,我也更新了答案。您可以使用“clone()”方法并配置多个 WebClient,而无需更改另一个。然后,您可以使用“@Qualifier”在服务类中自动装配您想要的服务。无需在服务类中创建WebClient。它是配置,因此最好将其放在 @Configuration 类中。它更清晰,你更接近单一责任原则。 (2认同)
  • 是的,方法是将它们设置在您创建 WebClient 的位置,即 Config 类 - MyApplicationConfiguration。所以你可以使用@Value注释来选择属性。顺便说一句,通常您不希望直接包含密码。即使已编码,也未加密,因此您仍然可以看到密码值。这是你不想要的,除非它只是一些个人项目,而不是每个人都能看到的公司。您可以对其进行加密,或者如果为云开发应用程序并使用例如 Kubernetes,则可以使用 Secrets。 (2认同)