网站首页 > 技术文章 正文
环境:Springboot2.6.14
如果你的应用程序调用远程REST服务,Spring Boot使用RestTemplate或WebClient使之非常的方便。
RestTemplate
如果需要从应用程序调用远程REST服务,可以使用Spring框架的RestTemplate类。由于RestTemplate实例通常需要在使用之前进行自定义,Spring Boot不提供任何单个自动配置的RestTemplate bean。但是,它可以自动配置一个RestTemplateBuilder,在需要时可以使用它创建RestTemplate实例。自动配置的RestTemplateBuilder确保合理的HttpMessageConverters应用于RestTemplate实例。
以下代码显示了一个典型示例:
@Service
public class RemoteService {
private final RestTemplate restTemplate ;
public RemoteService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build() ;
}
public Details storageService(Long storageId, Integer count) {
return this.restTemplate.getForObject("http://localhost:8080/storage/deduct/{storageId}/{count}", Boolean.class, storageId, count) ;
}
}
RestTemplateBuilder包括许多可用于快速配置RestTemplate的有用方法。例如,要添加BASIC身份验证支持,可以使用builder.basicAuthentication("admin","123").build()
自定义RestTemplate
RestTemplate定制有三种主要方法,这取决于你希望定制应用的范围。
要使任何自定义的范围尽可能窄,请注入自动配置的RestTemplateBuilder,然后根据需要调用其方法。每个方法调用都返回一个新的RestTemplateBuilder实例,因此自定义仅影响当前builder的使用。
要进行应用程序范围的附加定制,请使用RestTemplateCustomizer bean。所有这样的bean都会自动注册到自动配置的RestTemplateBuilder中,并应用于使用它构建的任何模板。
自动配置如下:
public class RestTemplateAutoConfiguration {
@Bean
@Lazy
@ConditionalOnMissingBean
public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer restTemplateBuilderConfigurer) {
RestTemplateBuilder builder = new RestTemplateBuilder();
return restTemplateBuilderConfigurer.configure(builder);
}
}
自定义配置
public class CustomRestTemplateCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
}
最后,可以定义自己的RestTemplateBuilder bean。这样做将替换自动配置的RestTemplateBuilder。如果你希望任何RestTemplateCustomizer bean应用于你的自定义Builder,就像自动配置所做的那样,使用RestTemplateBuilderConfigurer对其进行配置。下面的例子公开了一个RestTemplateBuilder,它与Spring Boot的自动配置相匹配,只是还指定了自定义连接和读取超时:
@Configuration(proxyBeanMethods = false)
public class CustomRestTemplateBuilderConfiguration {
@Bean
public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
return configurer.configure(new RestTemplateBuilder()).setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(2));
}
}
默认SpringBoot提供有RestTemplateBuilderConfigurer
public class RestTemplateAutoConfiguration {
@Bean
@Lazy
@ConditionalOnMissingBean
public RestTemplateBuilderConfigurer restTemplateBuilderConfigurer(
ObjectProvider<HttpMessageConverters> messageConverters,
ObjectProvider<RestTemplateCustomizer> restTemplateCustomizers,
ObjectProvider<RestTemplateRequestCustomizer<?>> restTemplateRequestCustomizers) {
RestTemplateBuilderConfigurer configurer = new RestTemplateBuilderConfigurer();
configurer.setHttpMessageConverters(messageConverters.getIfUnique());
configurer.setRestTemplateCustomizers(restTemplateCustomizers.orderedStream().collect(Collectors.toList()));
configurer.setRestTemplateRequestCustomizers(restTemplateRequestCustomizers.orderedStream().collect(Collectors.toList()));
return configurer;
}
}
使用系统默认的RestTemplateBuilderConfigurer是个明智选择,它合理配置了系统提供的默认HttpMessageConverters。
最极端(也很少使用)的选项是在不使用配置程序的情况下创建自己的RestTemplateBuilder bean。除了替换自动配置的构建器之外,这还可以防止使用任何RestTemplateCustomizer bean。
WebClient
如果你的类路径上有Spring WebFlux,你也可以选择使用WebClient来调用远程REST服务。与RestTemplate相比,这个客户端具有更强的功能性,并且是完全响应式的。
Spring Boot创建并预配置WebClient.Builder。强烈建议将它注入到组件中,并使用它创建WebClient实例。Spring Boot正在配置该构建器以共享HTTP资源,以与服务器相同的方式反映编解码器设置,等等。
以下代码显示了一个典型示例:
@Service
public class WebClientService {
private final WebClient webClient;
public WebClientService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("http://localhost:8080").build() ;
}
public Mono<Details> storageService(Long storageId, Integer count) {
return this.webClient.get().uri("/storage/deduct/{storageId}/{count}", storageId, count).retrieve().bodyToMono(Boolean.class) ;
}
}
WebClient运行时
Spring Boot将自动检测使用哪个ClientHttpConnector来驱动WebClient,这取决于应用程序类路径上可用的库。目前支持Reactor Netty、Jetty RS客户端和Apache HttpClient。
源码
public interface WebClient {
static WebClient.Builder builder() {
return new DefaultWebClientBuilder();
}
}
final class DefaultWebClientBuilder implements WebClient.Builder {
private static final boolean reactorClientPresent;
private static final boolean jettyClientPresent;
private static final boolean httpComponentsClientPresent;
static {
ClassLoader loader = DefaultWebClientBuilder.class.getClassLoader();
reactorClientPresent = ClassUtils.isPresent("reactor.netty.http.client.HttpClient", loader);
jettyClientPresent = ClassUtils.isPresent("org.eclipse.jetty.client.HttpClient", loader);
httpComponentsClientPresent =
ClassUtils.isPresent("org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient", loader) &&
ClassUtils.isPresent("org.apache.hc.core5.reactive.ReactiveDataConsumer", loader);
}
public WebClient build() {
ClientHttpConnector connectorToUse = (this.connector != null ? this.connector : initConnector());
// ...
return new DefaultWebClient(...) ;
}
private ClientHttpConnector initConnector() {
if (reactorClientPresent) {
return new ReactorClientHttpConnector();
} else if (jettyClientPresent) {
return new JettyClientHttpConnector();
} else if (httpComponentsClientPresent) {
return new HttpComponentsClientHttpConnector();
}
throw new IllegalStateException("No suitable default ClientHttpConnector found");
}
}
spring-boot-starter-webflux启动器默认依赖于io.projectreactor.netty:reactor-netty,它带来了服务器和客户端实现。如果选择使用Jetty作为响应式服务器,则应该在Jetty响应式HTTP客户端库上添加一个依赖项。对服务器和客户端使用相同的技术有其优点,因为它将自动在客户端和服务器之间共享HTTP资源。
开发人员可以通过提供自定义的ReactorResourceFactory或JettyResourceFactory bean来覆盖Jetty和Reactor Netty的资源配置——这将应用于客户端和服务器。
如果你希望覆盖客户端的选择,可以定义自己的ClientHttpConnector bean并完全控制客户机配置。
WebClient自定义
WebClient定制主要有三种方法,具体取决于你希望定制应用的范围。
为了使任何定制的范围尽可能窄,注入自动配置的WebClient.Builder,然后根据需要调用它的方法。WebClient.Builder实例是有状态的:builder上的任何更改都反映在随后用它创建的所有client上。如果你想用同一个builder创建多个客户端,你也可以考虑用WebClient.Builder other = builder.clone();
对所有WebClient进行应用程序范围的附加定制WebClient.Builder实例,你可以声明WebClientCustomizer bean并更改WebClient。在注入点的局部构建器。
最后,你可以使用原始API:WebClient.create()。在这种情况下,不会应用自动配置或WebClientCustomizer。
完毕!!!
求关注
SpringBoot对Spring MVC都做了哪些事?(一)
SpringBoot对Spring MVC都做了哪些事?(二)
SpringBoot对Spring MVC都做了哪些事?(三)
SpringBoot对Spring MVC都做了哪些事?(四)
Spring Retry重试框架的应用
spring data jpa 高级应用
Spring 强大的数据验证功能
Spring是如何解决循环依赖的?
Spring容器这些扩展点你都清楚了吗?
Spring任务执行与调度配置及使用详解
Spring中的@Configuration注解你真的了解吗?
Spring MVC 异步请求方式
Spring容器这些扩展点你都清楚了吗?
猜你喜欢
- 2024-10-13 谈谈springboot 获取前端json数据几种方法
- 2024-10-13 在Spring Boot中如何获取到Request对象?
- 2024-10-13 SpringBoot:如何优雅地进行响应数据封装、异常处理
- 2024-10-13 SpringBoot实现接口防抖的几种方案,杜绝重复提交
- 2024-10-13 @PostMapping @GetMapping注解 postmapping注解接收参数
- 2024-10-13 如何在SpringBoot中动态过滤JSON响应正文
- 2024-10-13 WebSocket 集群解决方案 websocket500
- 2024-10-13 SpringBoot跨系统调用接口方案 springboot跨越设置
- 2024-10-13 SpringBoot如何优雅的进行参数校验(一)
- 2024-10-13 IntelliJ IDEA必装插件以及SpringBoot使用小技巧合集
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)