今天我们分析ribbon 的源码,:先看依赖的jar包,通过SPI加载
1、点击实现类 RibbonAutoConfiguration 进入:这三部分很重要,一会回详解:Ribbon 客户端对象 ;configurations 引用的实例化对象过程和依赖注入
2、同时依赖这个jar,中间的类 LoadBalancerAutoConfiguration 也很重要:
3、点击进入,在ribbon调用时做了一个过滤作用
这里加上@LoadBalanced 注解的依赖注入,那么就只有加了@LoadBalanced 的实例才能注入 进来,其实里面有一个@Qualifier。
只是这里加上@LoadBalanced 注解才能依赖注入到源码中的,如果不加这个注解则没有 ribbon 功能,因为源码里面获取不到这个实例了 把拦截器设置到 restTemplate 中
4、restTemplate 的方法调用源码
5、进入 OAuth2RestTemplate
6、来到 AbstractClientHttpRequest
AbstractBufferingClientHttpRequest
7、来到InterceptingClientHttpRequest
8、 restTemplate 中设置的拦截器,拦截器先调用
到这看到多种过滤器:
9、来到 RibbonLoadBalancerClient
来到核心源码
获取 ILoadBalancer 类型的实例
10、来到 SpringClientFactory
11、来到:NamedContextFactory
先从缓存中拿服务列表:
12、根据服务名称创建一个容器,然后把容器根据服务名称缓存,这里在调用的时候获取容器的 ,目的是为了拿到最新的服务列表,所以 ribbon 在第一次服务名称调用的时候是比较慢的, 涉及到创建容器过程,第二次就直接从缓存里面拿容器对象了。
13、这里创建容器对象,并且把两个比较重要的类 register 进去了,register 其实就是把类变成 beanDefinition 对象,其实就是加载这两个类到容器中,触发这两个类重新获取服务列表
第一个注册的类:
第二个注册的类:
14、我们看看这两个类: EurekaRibbonClientConfiguration 创建 serverList 对象
15、在 DiscoveryEnabledNIWSServerList 类中有一个特别重要的方法
这个方法里面有一个方法是从本地从 eureka 服务端拉取到的服务列表的变量中获取到服务列表
16、这里的变量在客户端服务列表eureka拉取 时,放入里面的变量。
17、另外一个类 RibbonClientConfiguration 这个类中有一个非常重要的方法,serverList 是从第一个注册的类中实例化的,在这里依赖 注入进来了
返回的实例就是 ILoadBalanced 类型的,所以我们刚刚看到的
获取到的实例就是 ZoneAwareLoadBalancer 实例。在该类实例化的构造函数中,最终会调到
其父类的构造函数,里面有一个方法
18、OK 这里就掉到了这个核心方法,从本地服务列表中获取到了服务列表信息 在看看获取到这个实例化的接下来的操作
Server server = getServer(loadBalancer, hint);
这里就是根据前面从本地服务列表中获取到的列表信息,根据负载均衡算法从中获取到一个
接下来就是具体 http 调用了,又会走回去,进到没有拦截器的实例中
ribbon 源码大概分析结束,此源码相对是比较难的,大家一定改跟着这个思路多读几遍,慢慢领会其中的真谛,不明白的小伙伴欢迎留言!