热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

记一次SpringCloud微服务项目中Feign客户端创建失败问题排查

起因:在工作中进行微服务开发过程中,为将接口及实现分离(便于提供API模块给其他微服务模块调用),将Feign客户端接口定义与Feign客户端实现分别写在API模块与服务模块中,由

起因:

在工作中进行微服务开发过程中,为将接口及实现分离(便于提供API模块给其他微服务模块调用),将Feign客户端接口定义与Feign客户端实现分别写在API模块与服务模块中,由于以个人习惯定义包名,导致服务模块中创建Feign客户端失败,使用该客户端调用服务时,总会跳转到fallback定义(即服务降级)中。因为一开始没问题,修改了API模块及服务模块的包名之后,才出现问题,所以以这方面为思路去查找问题。

以下是代码复现(简约版) (注:本文后续代码仅展示关键部分)

feign客户端接口定义 -- 用户服务API模块

package com.personal.service.api.user.feign;
@FeignClient(
value = "user-service",
fallback = IUserClientFallback.class # 启动后调用服务发现都往该实现类跳转了
)
public interface IUserClient {
}

feign客户端实现 -- 用户服务模块

package com.personal.service.user.feign;
@RestController
public class UserClient implements IUserClient {
}

 Application类定义 -- 用户服务模块

package com.personal.service.user
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class UserApplication {
}

过程:

通过debug排查后,发现是Feign客户端创建失败。故而调用服务时,都会执行服务降级实现。

然后在同事的提醒下,参考之前的项目,将UserApplication类移到了包com.personal.service下之后,Feign客户端创建成功。

虽然问题解决,但是我不太明白问题的根本原因是什么,所以进行了一番探究学习。

发现与Application类的路径有关后,在Spring boot的官方文档中查找Spring boot关于Application类的规定及推荐。发现了这一句:

 意思是:@SpringBootApplication注解通常会被我们放在主类中,它隐含为项目定义了基本的搜索包。即,Spring boot项目通常会以这个注解所在的类的包路径为根去扫描bean定义(如果我们没有另外指定时)。

代码中,我的@SpringBootApplication注解在UserApplication中。

然后,通过对@EnableFeignClients的实现进行debug代码追踪:

该注解通过@Import注解引入了FeignClientsRegistrar类,并在其中完成Feign客户端bean的注册工作。

@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
}

进入到FeignClientsRegistrar类,其实现了ImportBeanDefinitionRegistrar接口,用于额外注册bean。找到注册bean定义的方法:

@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
registerDefaultConfiguration(metadata, registry);
registerFeignClients(metadata, registry);
}

找到注册Feign客户端的方法: registerFeignClients(metadata, registry);

 进入到 getBasePackages(metadata) 方法

所以会获取到UserApplication的包路径:com.personal.service.user,以该路径去扫描@FeignClient注解定义的Fegin客户端接口类。

但是我项目中的接口类路径为:com.personal.service.api.user.feign (文章一开始的代码复现中),故而找不到定义。Feign创建失败。至此,问题的根本原因找到。

结论:

使用Spring boot开发项目时,虽然提供给了我们很多便利,担其便捷的背后,也有着许多隐含的配置要求,所以我们要注意@SpringBootApplication注解定义的类的路径,在进行spring组件,即@Component、@Service等注解的bean时,如果我们未显式指定扫描包路径时,要注意定义的bean的包路径与Application类的包路径是否匹配。



推荐阅读
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • SpringBoot简单日志配置
     在生产环境中,只打印error级别的错误,在测试环境中,可以调成debugapplication.properties文件##默认使用logbacklogging.level.r ... [详细]
  • 感谢大家对IT十八掌大数据的支持,今天的作业如下:1.实践PreparedStament的CRUD操作。2.对比Statement和PreparedStatement的大批量操作耗时?(1 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文讨论了在ASP中创建RazorFunctions.cshtml文件时出现的问题,即ASP.global_asax不存在于命名空间ASP中。文章提供了解决该问题的代码示例,并详细解释了代码中涉及的关键概念,如HttpContext、Request和RouteData等。通过阅读本文,读者可以了解如何解决该问题并理解相关的ASP概念。 ... [详细]
author-avatar
手机用户2602922981
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有