ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 前言 * 在以往的单工程项目,所有代码都融合在一起,业务相互调用只需要引入共有的工具类或者对应模块的service。 * 到了微服务时代,已然不能使用这种方式,我们需要寻找新的解决方案。 * 若每个模块都把需要调用模块的service拷贝一份,那会令代码非常冗余,影响整个工程的健壮性。 * 稍大一些的系统,会分成多个库,比如用户库、订单库分开,订单服务想要取到用户的相关信息,由于不能 * 连接到用户的库,所以无法直接新建数据库查询以达到目的。 * 这个时候,远程调用方案出现,订单服务只需调用用户服务的API,就可以获取所需信息,非常方便。 * 我们下面来看下如何使用SpringCloud的Feign来进行微服务远程调用。 ## Feign简介 * Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服 * 务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。 ## 代码示例 1. 我们以 jpower-system 服务为例,让我们的 jpower-user 可以调用到 jpower-system 的API 2. 在jpower-system下新建了system-api工程,在该工程中新建package:com.wlcb.jpower.feign ![](https://img.kancloud.cn/f6/78/f6784b158f7888f6ec36bebe86b005de_698x496.png) 3. 在 com.wlcb.jpower.feign 下创建一个接口类,命名为 SystemClient 4. 增加如下代码,**下面代码是目前工程中已经实现的API接口** ~~~ /** * @author mr.gmac */ @FeignClient(value = AppConstant.JPOWER_SYSTEM, path = "/core/") public interface SystemClient { /** * @author null * @Description //TODO 查询部门所有下级部门id * @date 0:42 2020/9/3 0003 * @param id * @return com.wlcb.jpower.module.base.vo.ResponseData<java.lang.String> */ @GetMapping("/org/queryChildById") ResponseData<List<String>> queryChildOrgById(@RequestParam String id); @GetMapping("/org/queryOrgById") ResponseData<TbCoreOrg> queryOrgById(@RequestParam String orgId); @GetMapping("/client/getClientByClientCode") ResponseData<TbCoreClient> getClientByClientCode(@RequestParam String clientCode); @GetMapping("/function/getUrlsByRoleIds") ResponseData<List<Object>> getUrlsByRoleIds(@RequestParam List<String> roleIds); @GetMapping("/tenant/getTenantByCode") ResponseData<TbCoreTenant> getTenantByCode(@RequestParam String tenantCode); @GetMapping("/function/getMenuListByRole") ResponseData<List<TbCoreFunction>> getMenuListByRole(@RequestParam List<String> roleIds); @GetMapping("/dataScope/getAllRoleDataScope") ResponseData<List<TbCoreDataScope>> getAllRoleDataScope(); @GetMapping("/dataScope/getDataScopeByRole") ResponseData<List<TbCoreDataScope>> getDataScopeByRole(@RequestParam List<String> roleIds); } ~~~ 5. 继续新建`system-api-biz`工程maven继承 `system-api`,用来实现feign定义的接口,在工程中新建package:com.wlcb.jpower.controller ![](https://img.kancloud.cn/bc/5f/bc5fa449b68106e8d2f3a9faf7945f60_894x390.png) 6. 新建`SystemClientController`类,需要继承`SystemClient`接口类 ![](https://img.kancloud.cn/f3/82/f3825e02f2f04efb34084289623280cb_778x416.png) 7. 增加如下,因为Feign本质上是HTTP客户端,所以我们创建的 BlogClientImpl 其实就是 SpringMVC 的 Controller ,所以需要加上 @RestController 注解。 **以下代码是工程目前已经实现的代码** ~~~ @ApiIgnore @RestController @RequestMapping("/core") @AllArgsConstructor public class SystemClientController implements SystemClient { private CoreOrgService coreOrgService; private CoreClientService coreClientService; private CoreFunctionService coreFunctionService; private TenantService tenantService; private CoreDataScopeService coreDataScopeService; @Override @GetMapping("/org/queryChildById") public ResponseData<List<String>> queryChildOrgById(@RequestParam String id){ return ReturnJsonUtil.ok("查询成功",coreOrgService.queryChildById(id)); } @Override @GetMapping("/function/getUrlsByRoleIds") public ResponseData<List<Object>> getUrlsByRoleIds(@RequestParam List<String> roleIds) { return ReturnJsonUtil.ok("查询成功",coreFunctionService.getUrlsByRoleIds(roleIds)); } @Override @GetMapping("/function/getMenuListByRole") public ResponseData<List<TbCoreFunction>> getMenuListByRole(@RequestParam List<String> roleIds) { return ReturnJsonUtil.ok("查询成功",coreFunctionService.getMenuListByRole(roleIds)); } @Override @GetMapping("/dataScope/getAllRoleDataScope") public ResponseData<List<TbCoreDataScope>> getAllRoleDataScope() { return ReturnJsonUtil.ok("查询成功",coreDataScopeService.getAllRoleDataScope()); } @Override @GetMapping("/dataScope/getDataScopeByRole") public ResponseData<List<TbCoreDataScope>> getDataScopeByRole(@RequestParam List<String> roleIds) { return ReturnJsonUtil.ok("查询成功",coreDataScopeService.getDataScopeByRole(roleIds)); } @Override @GetMapping("/tenant/getTenantByCode") public ResponseData<TbCoreTenant> getTenantByCode(@RequestParam String tenantCode){ return ReturnJsonUtil.ok("查询成功",tenantService.getOne(Condition.<TbCoreTenant>getQueryWrapper().lambda().eq(TbCoreTenant::getTenantCode,tenantCode))); } @Override @GetMapping("/org/queryOrgById") public ResponseData<TbCoreOrg> queryOrgById(@RequestParam String orgId) { return ReturnJsonUtil.ok("查询成功",coreOrgService.getById(orgId)); } @Override @GetMapping("/client/getClientByClientCode") public ResponseData<TbCoreClient> getClientByClientCode(@RequestParam String clientCode) { return ReturnJsonUtil.ok("查询成功",coreClientService.loadClientByClientCode(clientCode)); } } ~~~ 8. 在`jpower-user`下的`user-biz`工程的 pom.xml 文件引入`jpower-system`的API包 ![](https://img.kancloud.cn/a9/20/a9207b5bdca96f42f0693448737cd04d_1412x1532.png) 9. 找到`UserController`,新增如下代码 ~~~ private SystemClient systemClient; @GetMapping(value = "/orgDeatil",produces="application/json") public ResponseData<TbCoreOrg> orgDeatil(String id){ ResponseData<TbCoreOrg> r = systemClient.queryOrgById(id); return r; } ~~~ 10. 启动工程,我们去调用查看API调用返回结果 ![](https://img.kancloud.cn/8d/4f/8d4f4cb1af05244830ef2e43130edadb_2912x1476.png) 11. 我们可以看到我们请求jpower-user服务的接口成功通过feign调用jpower-system查出了数据。 ## 后续 * 下面我们来看下 Sentinel 熔断机制