一、背景
最近在看在使用Spring Cloud
的时候发现,当我们通过Feign
去调用别的微服务时,当我们有多个Feign客户端(比如:用户微服务、商品微服务)时,是可以为每个Feign客户端配置不同的实现,比如:用户微服务使用Feign默认的契约,而商品微服务可以使用Spring MVC 的契约格式,那么这个是怎么实现的呢?此处我们写一个简单的例子来模拟一下。
二、需求
假设我们存在一个 CommonApi
的接口,用户微服务(user)和我们的调用方分别实现这个接口,实现不同的功能,而我们的产品微服务(product)不实现这个接口,默认采用调用方的实现。
调用方(父上下文)
实现 CommonApi 接口,兜底实现,如果被调用方没实现,则采用这个,否则采用被调用方自己的逻辑。
user微服务(子上下文)
实现 CommonApi 接口
product微服务(子上下文)
不实现 CommonApi 接口。
在调用方,会同时调用 user微服务和product微服务 中的 CommonApi 接口,当被调用方自己实现了CommonApi接口时,使用被调用方自己的逻辑,如果被调用方没有实现,则使用调用方自己的逻辑。
即我们要实现的效果:
1、在调用方程序中,自己的上下文中获取到的 CommonApi
是调用方自己实现的。
2、在调用方程序中,使用 用户服务 的上下文中获取到的 CommonApi
是用户服务实现。
3、在调用方程序中,使用 商品服务 的上下文中获取到的 CommonApi
是调用方实现的,因为商品服务自己没有实现。
如果我们把 CommonApi
理解为Feign
中的feign.Contract
,那么在 用户服务 中就是我们修改了Feign默认的Contract,而 产品服务 就是使用的默认的Contract。
三、实现步骤
1、基础代码编写
2、测试结果
四、小彩蛋
Spring Cloud OpenFeign
中父子上下文的实现。
FeignContext
实现了 NamedContextFactory
接口,NamedContextFactory中有个org.springframework.cloud.context.named.NamedContextFactory#createContext
方法,可以看到父子上下文是如何建立的。
五、完整代码
代码链接:https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/spring-parent-child-context