使用
- 接口上加上FeignClient注解
- 启动类加上EnableFeignClients注解。
实现过程
- 注解EnableFeignClients导入了FeignClientsRegistrar,在这个类中对FeignClients的定义进行组装。实际是一个FeignClientFactoryBean对象。
- FeignClientFactoryBean实现了FactoryBean接口所以在spring在进行依赖注入时得到的是一个getObject返回的对象。
- 继续跟代码,看一下gatObject方法。builder是SentinelFeign的builder因为我启用了Sentinel。
- 跟踪loadBalance方法。LoadBalancerFeignClient在DefaultFeignLoadBalancedConfiguration类自动装配,HystrixTargeter在FeignAutoConfiguration类中自动装配。
- 跟踪target方法。返回的是ReflectiveFeign,同时设置了一个InvocationHandlerFactory。SentinelTargeterAspect.getFeignClientFactoryBean获取的是通过切面得到的步骤4target方法的第一个 参数。
- InvocationHandlerFactory的create返回的InvocationHandler就是FeignClient标注的接口的实现,这里返回的是SentinelInvocationHandler。
- 再看一下步骤5中的newInstance方法。在这个方法中完成了对接口方法的映射和对类的代理。factory是步骤5中设置的InvocationHandlerFactory,methodToHandler保存的是FeignClient接口中的方法与实现的映射。
- 当我们调用接口方法时实际是使用SentinelInvocationHandler在处理。
- 真正处理逻辑在MethodHandler中。在步骤7中提到的newInstance方法第一句就创建了MethodHandler。factory是在步骤5创建ReflectiveFeign时传入的SynchronousMethodHandler.Factory。
- SynchronousMethodHandler.Factory的create返回SynchronousMethodHandler。下面是SynchronousMethodHandler的invoke方法,在executeAndDecode方法中调用的Client是LoadBalancerFeignClient,下面就是负载,组装请求路径。
总的来说就是对接口进代理,对每个方法生成一个实现,在实现中组装请求路径,使用配置的服务名与负载均衡选择一个服务地址,将请求路径中的服务名替换为服务地址发送请求。