一.关于RestTemplate的三种创建方式
最早接触RestTemplate是学到微服务间服务的通信使用http的rest风格在应用层进行通信,不过视频讲的很少,我就决定自己做一个总结,不过由于没有接触过restTemplate请求中发送cookie或者jwt等,所以业务方面可能写的简单点.
RestTemplate的主要三种配置方式有
- 使用RestTemplateBuilder来配置超时信息
- 使用RestTemplateCustomizer来自定义化配置
- 使用RestTemplateCustomizer和RestTemplateBuilder结合配置
1.使用RestTemplateBuilder来进行配置
下图是springApi 2.7.3关于RestTemplateBuilder的解释
大致意思:restTemplateBuilder是一个生成restTemplate的类,可以很方便的注册errorHandler,MessageConverts,URL模板,超时时间的设置等,同时这个类会被自动注册为bean,你可以在需要的地方直接注入。
下面是一个简单的使用:
@Configuration
public class BaseConfiguration {
@Autowired
LoadBalancerClient loadBalancerClient;
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){
return restTemplateBuilder
.additionalInterceptors(new LoadBalancerInterceptor(loadBalancerClient))
.setConnectTimeout(Duration.ofSeconds(5))
.build();
}
2.使用RestTemplateCustomizer来自定义
Customizer的意思本身就是定制器,我们查看springAPi的解释:
值得一提的是,RestTemplatecustomizer分别在两个包中都有定义,分别是:
1.org.springframework.boot.web.client.RestTemplateCustomizer;
2.org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer
按照boot api的定义,我认为是通过RestTemplateCustomizer来定义的,两个接口的内部方法差不多,第二个的官方文档没有找到,决定使用第一个
官方api的意思翻译过来就是:通过实现这个接口的customize(RestTemplate restTemplate)这个回调函数,可以给RestTemplate进行定制。
下面是简单的使用:
一个简单的拦截器:
// 自定义一个简单的拦截器
package com.interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
public class CustomRestTemplateCustomizerInterceptor implements ClientHttpRequestInterceptor {
private static final Logger logger = LoggerFactory.getLogger(CustomRestTemplateCustomizerInterceptor.class);
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
logDetails(request);
return execution.execute(request, body);
}
public void logDetails(HttpRequest request){
logger.info("url:{}",request.getURI());
logger.info("method:{}",request.getMethod());
logger.info("header:{}",request.getHeaders());
}
}
回调函数中添加进去这个拦截器
package com.bean;
import com.interceptor.CustomRestTemplateCustomizerInterceptor;
import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.web.client.RestTemplate;
public class CustomRestTemplateCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
// 自定制interceptor
restTemplate.getInterceptors().add(new CustomRestTemplateCustomizerInterceptor());
}
}
将我们写的定制器注册为bean
@Bean
public CustomRestTemplateCustomizer customRestTemplateCustomizer(){
return new CustomRestTemplateCustomizer();
}
运行试试:
可以看到我们的通过定制器自定义的拦截器起了作用。
3.使用RestTemplateCustomizer和RestTemplateBuilder结合配置
这是一个破坏性最大,也是定制性最高的方式,至于破坏性,我们在后面说,先来说一说这种的如何配置
@Bean
@DependsOn({"customRestTemplateCustomizer"})
public RestTemplateBuilder restTemplateBuilder(CustomRestTemplateCustomizer customRestTemplateCustomizer){
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(customRestTemplateCustomizer);
System.out.println("添加了定制器的"+restTemplateBuilder);
return restTemplateBuilder;
}
这种配置是将定制器作为参数传入到RestTemplateCustomizer的构造方法中去。
疑问1:我们构造为bean的RestTemplateCustomizer会不会和自动构造的(前文有提到)RestTemplateCustomizer产生冲突还是覆盖?
实验1:
代码:
@Configuration
public class BaseConfiguration {
@Autowired
LoadBalancerClient loadBalancerClient;
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder){
// mark1
System.out.println("这是第一个方法里面的"+restTemplateBuilder);
return restTemplateBuilder
.additionalInterceptors(new LoadBalancerInterceptor(loadBalancerClient))
.setConnectTimeout(Duration.ofSeconds(5))
.build();
}
@Bean
public CustomRestTemplateCustomizer customRestTemplateCustomizer(){
return new CustomRestTemplateCustomizer();
}
@Bean
@DependsOn({"customRestTemplateCustomizer"})
public RestTemplateBuilder restTemplateBuilder(CustomRestTemplateCustomizer customRestTemplateCustomizer){
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(customRestTemplateCustomizer);
// mark2
System.out.println("添加了定制器的"+restTemplateBuilder);
return restTemplateBuilder;
}
}
我们看到写了两个mark标记,查看这两个是不是同一个RestTemplateBuilder。
运行查看输出:
我们可以看到这里我们自己构造的RestTemplateBuilder完全覆盖了框架提供的RestTemplateBuilder。
疑问2:为什么说这种方式的破坏性极大
实验2:我们首先不定制,打断点之后查看框架提供的RestTemplateBuilder有哪些属性:
这是不自定义得到的框架提供的RestTemplateBuilder,我们可以看到有许多的消息转换器
我们通过刚刚的代码定制覆盖之后查看缺少了那些属性:
我们可以看到缺少了消息转换器以及定制器的数量也发生了变化。
以上就是三种不同的生成RestTemplate的方式。
RestTemplate的原理以及代码解析:暂时写作中
标签:RestTemplateCustomizer,RestTemplate,RestTemplateBuilder,import,public,restTempla From: https://www.cnblogs.com/oldoldcoder/p/16786056.html