SpringCloud Ribbon原理-2-LoadBalanced注解的restTemplate调用流程

在上文基础之上 ,来分析加上了@LoadBalanced注解的 restTemplate的getForObject具体过程
在这里插入图片描述
上图中,鼠标光标放在getForObject上面,按住ctrl +alt + B, 查找这个方法的实现:
在这里插入图片描述
execute方法中又调用了doExecute方法:
在这里插入图片描述
在这里插入图片描述
上面这个方法里面有两个操作:ClientHttpRequest request = createRequest(url, method); 方法得到一个ClientHttpRequest, 然后调用这个request的execute方法,这里需要注意的是,既然是调用了request的execute,那么必须要弄清楚这个request是谁!进入createRequest方法,发现它是工厂模式创建的,ctrl alt +B 打开实现,确定它用的是哪个工厂去创建的
在这里插入图片描述
可以看到只有两个选项,而抽象类HttpAccessor中并未提供具体实现,
在这里插入图片描述
因此,这个工厂就是InterceptingHttpAccessor,这个getRequestFactory()方法是 InterceptingHttpAccessor类中去实现的,并且,当
在这里插入图片描述
上图代码中可以看到,当interceprors不为空时,返回了 InterceptingClientHttpRequestFactory。我们还应注意到,
getRequestFactory()方法中有一行代码: List interceptors = getInterceptors(); 我们先看下这个interceptors 是什么: 在这里插入图片描述
而interceptors 赋值是在setInterceptors 方法里面:
在这里插入图片描述
鼠标放在setInterceptors 方法上面,按住ctrl + 鼠标左键,就可以看到这个方法在哪里被调用了,通过IDEA的提示,我们知道这个拦截器实在 org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig#restTemplateCustomizer 方法中赋值的。
在这里插入图片描述
在这里插入图片描述
上面我们知道了createRequest的工厂是InterceptingClientHttpRequestFactory ,再回到org.springframework.http.client.support.HttpAccessor#createRequest 这个方法里面,来查找一下createRequest是怎么创建的:
在这里插入图片描述
发现124行createRequest方法的实现中并没有 InterceptingClientHttpRequestFactory 这个类,而getRequestFactory() 返回的是InterceptingClientHttpRequestFactory ,因此,我们只能去它的父类中去寻找蛛丝马迹:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里,我们知道了org.springframework.web.client.RestTemplate#doExecute 中ClientHttpRequest request = createRequest(url, method); 方法返回的是
InterceptingClientHttpRequest
,因此后面调用的execute应该是 InterceptingClientHttpRequest中的execute方法,但是,很不幸,request.execute方法的实现,并没有出现InterceptingClientHttpRequest:
在这里插入图片描述
因此这里肯定又是一个模板方法的调用,我们直接从父类抽象类org.springframework.http.client.AbstractClientHttpRequest#execute 中去找,但是父类中又调用了一个模板方法executeInternal方法:
在这里插入图片描述
四个实现类,该选哪个呢?由于上面还是没有看到InterceptingClientHttpRequest,只能继续从父类AbstractBufferingClientHttpRequest中寻找实现,这个类里面也是模板方法,不过这个类中的executeInternal 方法的实现中,最终找到了InterceptingClientHttpRequest:
在这里插入图片描述
也就是,restTemplate类中的request.execute方法,最终调用到了org.springframework.http.client.InterceptingClientHttpRequest#executeInternal 这个方法:
在这里插入图片描述
这里是调用了InterceptingClientHttpRequest内部类InterceptingRequestExecution的execute方法,方法里面又调用了之前创建的拦截器:
在这里插入图片描述
然后调用了拦截器的inetercept方法,这个intercept方法的实现是在LoadBalancerInterceptor中:
在这里插入图片描述
debug进去,发现最终的执行是 this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution))
在这里插入图片描述
拦截器最终把execute委托给了this.loadBalancer去执行,而this.loadBalancer 是RbibbonAutoConfiguration中自动装配好的RibbonLoadBalancerClient :
在这里插入图片描述
来看下RibbonLoadBalancerClient 中是如何实现的
在这里插入图片描述
RibbonLoadBalancerClient 中有两个关键步骤 1. 获取一个负载均衡器 2。根据负载均衡器拿到一个Server:

	ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
	Server server = getServer(loadBalancer, hint);

猜你喜欢

转载自blog.csdn.net/weixin_41300437/article/details/109268096