SpringCloud中RestTemplate集成Ribbon源码分析

SpringCloud中RestTemplate集成Ribbon源码分析

前言

包版本可以自己根据自己项目来就行,我这里使用的spring-boot-starter-parent版本是2.3.12.RELEASE,spring-cloud-dependencies版本是Hoxton.SR12,spring-cloud-alibaba-dependencies版本是2.2.9.RELEASE。

配置RestTemplate

在SpringCloud项目中RestTemplate集成Ribbon需要自己定义一个RestTemplate的Bean,使用@LoadBalanced标记就能使用Ribbon来做负载均衡了。

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    
    
        return new RestTemplate();
    }

使用示例

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/m1")
    public String m1(){
    
    
        String url = "http://user-app/user-info/info/666";  // 替换为实际的请求 URL
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
// 处理响应数据
        System.out.println("Status code-------------------: " + response.getStatusCodeValue());
        System.out.println("Response body----------------------: " + response.getBody());
        return response.getBody();
    }

源码加载过程分析

  • 1、首先我们会自定义一个RestTemplate的Bean,通过@Bean的方式将RestTemplate加载到IOC中,这里我们集成Ribbon能看到的是直接使用了一个@LoadBalanced注解,这个注解Spring是不认识的,是由spring-cloud-commons包提供的LoadBalancerAutoConfiguration配置类来进行加载的,这个LoadBalancerAutoConfiguration配置类会通过SpringBoot提供的加载META-INF/spring.factories文件中自动加载配置类来实现被Spring加载。
    在这里插入图片描述
  • 2、知道是那一个类来进行的RestTemplate和Ribbon集成,那么现在来看看这个配置类。

在这里插入图片描述

  • 3、我们能从LoadBalancerAutoConfiguration这个配置类中看到,这里会注入一个RestTemplate的集合,并且注入的时候还使用到了@LoadBalanced注解,我们来看看@LoadBalanced注解,发现这个注解里面加了一个@Qualifier限定符注解,在Spring做依赖注入的时候会对这个注解进行判断如果加了@LoadBalanced那么只会注入同样被@LoadBalanced注解标记的bean,@Qualifier还有一个作用可以通过指定的bean名称匹配bean。
    在这里插入图片描述

  • 4、结合以上所述我们知道在LoadBalancerAutoConfiguration中我们会获取到所有被@LoadBalanced注解标记的bean,然后我们继续往下看这个类里面东西挺多的一下子也不知道要看什么,有个方法可以快速定义要看的核心方法,我们这里竟然是要对RestTemplate进行处理,而且这里也获取到了一个RestTemplate数组,那么这里我们就直接查看restTemplates在哪里使用了,在使用的地方打个断点就行,从这个方法中我们可以看到这里循环遍历restTemplates然后传入RestTemplateCustomizer的customize方法,看到这里已经可以猜到肯定是在RestTemplateCustomizer这个类中进行的处理,直接进入函数对象里面这个断点,然后使用F7进入customizer.customize(restTemplate)实际调用内部看看。
    在这里插入图片描述

  • 5、这里会调用LoadBalancerAutoConfiguration的一个静态内部类LoadBalancerInterceptorConfigrestTemplateCustomizer加载的对象,这里会对传入的RestTemplate对象进行restTemplate.setInterceptors(list)设置拦截器列表,并且这里有一个拦截器中的loadBalancer是Ribbon的,那基本上就能确定RestTemplate集成Ribbon就是使用的拦截器。
    在这里插入图片描述

  • 6、结合以上所述我们还可以看看LoadBalancerInterceptorConfig,这里面的另外一个方法,loadBalancerInterceptor方法封装一个拦截器这个拦截器中会存放一个负载均衡器,在restTemplateCustomizer这个方法使用的就是loadBalancerInterceptor封装的拦截器对象,在restTemplateCustomizer方法中return的RestTemplateCustomizer接口只有一个方法void customize(RestTemplate restTemplate)传入一个RestTemplate类型的对象,这里会对传入的RestTemplate对象进行restTemplate.setInterceptors(list)设置拦截器列表。
    在这里插入图片描述

  • 7、到这里RestTemplate就封装好了,接下来就是看在调用接口的时候是如何获取的真实url了。

  • 8、我们会通过restTemplate.exchange来调用,这里自己断点进入exchange方法一直往下面跟就行,我这里会跳过一些流程,直接定位核心方法。
    在这里插入图片描述

  • 9、调用restTemplate.exchange后面实际会调用到RestTemplate的doExecute方法,这里面可以看到封装的ClientHttpRequest请求对象是InterceptingClientHttpRequest类型,这个对象里面可以看到我们之前设置的拦截器。
    在这里插入图片描述

  • 10、然后调用InterceptingClientHttpRequest 的父抽象类AbstractClientHttpRequestexecute的execute方法,最终会创建一个InterceptingRequestExecution类型对象调用它的execute方法,这里面会去执行每个拦截器的intercept方法。
    在这里插入图片描述

  • 11、最终会走到我们在LoadBalancerAutoConfiguration设置的RestTemplate的LoadBalancerInterceptor中,这里可以看到会使用我们设置的RibbonLoadBalancerClient去调用execute方法Ribbon的逻辑。
    在这里插入图片描述

到这里整个流程基本上就结束了,有兴趣的可以继续跟踪后面的执行逻辑看看Ribbon是怎么处理服务名称获取服务列表发起真实调用的

猜你喜欢

转载自blog.csdn.net/weixin_44606481/article/details/131619926