温故知新(一)—— RestTemplate

一、准备

Spring Boot :2.0.8.RELEASE
Spring Cloud : Finchley.SR2
Nacos : 0.8.0
建立两个工程;Nacos作为注册中心。
工程1:provider,只简单的提供一个接口provider

@SpringBootApplication
@EnableDiscoveryClient
@RestController
@Slf4j
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
    @GetMapping("provider")
    public String provider(){
        log.info("..................................");
        return "i am provider";
    }
}

工程2:consume,只简单的采用RestTemplate进行调用provider

@SpringBootApplication
@Slf4j
@EnableDiscoveryClient
@RestController
public class ConsumeApplication {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    @Autowired
    RestTemplate restTemplate;
    public static void main(String[] args) {
        SpringApplication.run(ConsumeApplication.class, args);
    }
    @GetMapping("test")
    public String getContent(){
        log.info("发起请求");
        return restTemplate.getForObject("http://provider/provider",String.class);
    }

}

二、RestTemplate

2.1 RestTemplate类图

在这里插入图片描述
RestTemplate集成InterceptingHttpAccessor、实现RestOption;InterceptingHttpAccessor继承HttpAccess;

2.2执行流程

用postman发起请求http://locahost:7777/test;即调用consume工程的test接口,之后通过RestTemplate向provider服务发起请求

    @GetMapping("test")
    public String getContent(){
        log.info("发起请求");
        return restTemplate.getForObject("http://provider/provider",String.class);
    }

之后会调用RestTemplate的doExecute接口
在这里插入图片描述
最重要的是第683行调用父类的createRequest方法获取ClientHttpRequest,HttpAccessor中的createRequest

protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
		ClientHttpRequest request = getRequestFactory().createRequest(url, method);
		if (logger.isDebugEnabled()) {
			logger.debug("Created " + method.name() + " request for \"" + url + "\"");
		}
		return request;
	}

getRequestFactory()获取ClientHttpRequestFactory,因为InterceptingHttpAccessor重写了getRequestFactory,
在这里插入图片描述
这里主要做两件事情:1.判断是否有拦截器ClientHttpRequestInterceptor,如果有那么就生成InterceptingClientHttpRequestFactory;2.如果没有那么获取默认的ClientHttpRequestFactory,默认为SimpleClientHttpRequestFactory。

注意下面这句

factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);

InterceptingClientHttpRequestFactory只是个包装者,super.getRequestFactory()真正的ClientHttpRequestFactory还是SimpleClientHttpRequestFactory。

因为SpringCloud默认集成了Ribbon,默认注入了Ribbon的RibbonLoadBalancerClient,代码在LoadBalancerAutoConfiguration,注意这个注解**@ConditionalOnMissingClass(“org.springframework.retry.support.RetryTemplate”)** ,后面我们再介绍RetryTemplate。
在这里插入图片描述
回到HttpAccessor的createRequest,经过上面的流程已经得到了ClientHttpRequestFactory,之后就创建ClientHttpRequest了。
经过这些步骤就创建好了一个ClientHttpRequest。
回到RestTemplate的 doExecute方法
在这里插入图片描述
request.execute();执行请求;执行AbstractClientHttpRequest的execute()
在这里插入图片描述
执行最终执行InterceptingClientHttpRequest的executeInternal
在这里插入图片描述
InterceptingRequestExecution的execute
在这里插入图片描述
注意红框内:前文有提到Ribbon的负载均衡拦截器LoadBalancerIntercetor,通过该拦截器采用Ribbon实现负载均衡。LoadBalancerInterceptor:
在这里插入图片描述
LoadBalancerClient为RibbonLoadBalancerClient;到这里就调用Ribbon相关的内容了。

Ribbon流程

执行RibbonLoadBalancerClient的Excute
在这里插入图片描述
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);得到负载均衡ZoneAwareLoadBalancer,获取服务地址Server server = getServer(loadBalancer);执行请求execute,这里不再详细赘述,后面温故而知新Ribbon再详细介绍。

源码地址

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值