spi 加载
这里加上@LoadBalanced 注解的依赖注入,那么就只有加了@LoadBalanced 的实例才能注入 进来,其实里面有一个@Qualifier
只是这里加上@LoadBalanced 注解才能依赖注入到源码中的,如果不加这个注解则没有 ribbon 功能,因为源码里面获取不到这个实例
把拦截器设置到 restTemplate 中
创建 Ribbon 客户端对象
configurations 引用的实例化对象过程
restTemplate 的方法调用源码
restTemplate 中设置的拦截器,拦截器先调用
核心源码
获取 ILoadBalancer 类型的实例
根据服务名称创建一个容器,然后把容器根据服务名称缓存,这里在调用的时候获取容器的 目的是为了拿到最新的服务列表,所以 ribbon 在第一次服务名称调用的时候是比较慢的, 涉及到创建容器过程,第二次就直接从缓存里面拿容器对象了。
这里创建容器对象,并且把两个比较重要的类 register 进去了,register 其实就是把类变成 beanDefinition 对象,其实就是加载这两个类到容器中,触发这两个类重新获取服务列表
第一个注册的类:
第二个注册的类:
我们看看这两个类: EurekaRibbonClientConfiguration 创建 serverList 对象
在 DiscoveryEnabledNIWSServerList 类中有一个特别重要的方法
这个方法里面有一个方法是从本地从 eureka 服务端拉取到的服务列表的变量中获取到服务 列表
另外一个类 RibbonClientConfiguration 这个类中有一个非常重要的方法,serverList 是从第一个注册的类中实例化的,在这里依赖 注入进来
返回的实例就是 ILoadBalanced 类型的,所以我们刚刚看到的
获取到的实例就是 ZoneAwareLoadBalancer 实例。在该类实例化的构造函数中,最终会调到 其父类的构造函数,里面有一个方法
这里就掉到了这个核心方法,从本地服务列表中获取到了服务列表信息
在看看获取到这个实例化的接下来的操作
Server server = getServer(loadBalancer, hint);
这里就是根据前面从本地服务列表中获取到的列表信息,根据负载均衡算法从中获取到一个
接下来就是具体 http 调用了,又会走回去,进到没有拦截器的实例中