前言
openfeign可以方便的进行远程服务调用。仅仅只需要添加注解和添加与被调用方一致的方法签名即可完成。通过断点,可以发现我们注入的feign客户端其实是一个代理对象,也就是说Spring根据我们写的接口为我们生成了一个代理对象。现在通过openfeign的源码来了解这中间的过程。
源码分析
FeignClient注入
在启动类上,我们通过注解@EnableFeignClients
开启了Feign客户端。通过注解源码中的注释可以知道,当我们使用了该注解时,SpringBoot回去扫描那些被@FeignClients
标注的接口。可以通过属性basePackages
配置我们需要扫描的包。另外,在注解类的上面导入了另一个类:FeignClientsRegistrar
。通过类名称我们知道该类负责了FeignClients的注册。
进入类FeignClientsRegistrar
中,首先有个方法registerBeanDefinitions
用来注册beanDefinition,其中就包括了方法registerFeignClients
。
在方法registerFeignClients
中完成了我们所有的feignClients的注册。先看方法的前半部分。
这里是对注解@EnableFeignClients
的一个解析。首先判断是否设置了属性clients
,如果设置了那么就不再去扫描包,而是直接使用设置的clients;如果没有设置,那么就会去扫描包下面的类。
接下来是方法registerFeignClients
的后半部分,完成每个扫描出来的feignClient的注入工作。
关于我们在注解@FeignClient
中的属性配置,全部都在方法registerFeignClient
中进行了配置,最后才进行了beanDefinition的注入工作。
在这里有一个关键的方法入口:
在这个方法内,将完成feignClient的实例化。具体过程,我们继续深入了解。
进入方法后,首先会配置下feignClient的相关属性值,然后传入方法loadBalance
中,进入方法:
一直到最后,我们会进入到类ReflectiveFeign
中的newInstance
方法。
终于,执行到这里,便完成了feignClient接口的代理对象的实例化。最后注入容器即可。
FeignClient的调用过程
从上面的源码分析我们知道:我们在实际发起调用的时候,使用的是一个FeignClient的代理对象。因此在执行接口的相关方法时,必定会执行代理对象的invoke
方法。
依旧回到ReflectiveFeign
类中,查看其invoke
方法。
在这个方法里面,首先根据方法名排除掉几个常见的特殊的方法。最后执行目标方法。
继续进入方法executeAndDecode
:
最终,可以看到在这里发起了http请求,并对返回结果进行了处理。
以上就是关于openFeign的一些源码分析。