RibbonLoadBalancerClient初始化
1、先看下两个自动配置类
- 其中RibbonAutoConfiguration配置类创建了SpringclientFactory和LoadBanlancerClient即RibbonLoadBalancerClient
注意:SpringClientFactory设置了configurations,这个configurations是配置类属性,且含有注解@Autowired,作用是加载RibbonClientSpecification类型的对象这个类型的对象和@RibbonClients注解相关,此注解在注册定义信息时更改了name
故在对factory设置congfigurations时数据如下
SpringClientFactory的setConfigurations方法其实调用的是父类的方法(NamedContextFactory)
- LoadBalancerAutoConfiguration配置类中创建了SmartInitializingSingleton和RestTemplateCustomizer以及LoadBalancerInterceptor
对于spring中的SmartInitializingSingleton类型的对象创建后会调用其afterSingletonsInstantiated方法
restTemplates集合是根据 @LoadBalanced注解在spring容器中获取的,注解信息如下
至此,会将spring环境中的RestTemplate(含@LoadBalanced注解的)设置拦截器LoadBalancerInterceptor完成
LoadBalancerInterceptor的实例化
拦截器构造方法中的loadBalancer和requestFactory分别为上面自动配置类提供的
RibbonLoadBalancerClient和SpringClientFactory
使用RestTemplate调用服务时会调用拦截器的intercept方法,如上图,拦截方法中会调用loadBalancer的execute方法
RibbonLoadBalancerClient的execute方法
主图1
1、getLoadBalancer
调用了clientFactory的getLoadBalancer方法
进入父类方法(NamedContextFactory)
2、根据服务名称获取context,并将服务名称和context建立映射关系
会将RibbonEurekaAutoConfiguration中的configurations取出来进行注册到当前context,同时也会将defaultConfigType类型Class进行注册,defaultConfigType是在创建对象时传过来的(RibbonClientConfiguration)
下图表示两类注册过程
同时还会给这个context的环境变量赋值(propertyName是在创建对象是传过来的默认的ribbon.client.name),即查询服务的name
3、RibbonClientConfiguration配置类
name属性是和context相关的,每次都会创建新的context,且对应新的RibbonClientConfiguration配置类,以及新的环境变量${ribbon.client.name} ----查询的服务id(服务名称)
创建了ILoadBalancer对象(ZoneAwareLoadBalancer)即上面标题1中getLoadBalancer需要的对象类型,如下图,继续回到SpringClientFactory的getInstance方法
继续返回到RibbonLoadBalancerClient的execute方法(见上面主图1)
4、getServer(见上面主图1)
根据loadBalancer获取服务对象,进入代码
调用loadBalancer的chooseServer方法
进入ZoneAwareLoadBalancer对象的chooseServer方法
会判断可用服务数量,如果只有一个则直接调用父类chooseServer方法
此时的规则rule是默认的Round
从loadBalance中选择一个服务,并返回
总结:RibbonLoadBalancerClient代替restTemplate执行execute方法的大致流程基本上是这样,写的可能有点乱,慢慢跟着代码基本都能看懂大致流程(注意:注册中心的服务信息是在创建loadBalance时加载的)