zoukankan      html  css  js  c++  java
  • spring-boot-devtools 不同ClassLoader引起的问题

    问题场景:因业务需求,需要在请求到达接口时,进行IP获取。并且需要根据IP进行相关处理,由于其它系统有使用到的可能,于是在外部新创建了一个jar包,在该jar包中使用FeignClient的方式,调用业务接口,具体实现如下:
    然后在具体需要拦截IP的方法上,加上该注解。
    然后再在启动类上,添加该jar包的扫描。
    启动服务。
    突然发现,服务启动失败,并提示 实例化CheckIpAspect失败,原因是,找不到DataSyncServiceApi这个Bean。按照往常的经验,是没有添加该Api的包扫描,于是去启动类检查。
    但是,很不辛的是,@EnableFeignClients上是加了这个类的包扫描的。
    那说明,不是包扫描的问题。
    突然想起另一个服务也加了拦截IP的注解,于是抱着尝试的心态,启动了一下。结果居然成功了。
    仔细对比两个启动类上的配置。
    发现出问题的服务多了一个注解
    @EnableCheckFeign ,这个注解是我们项目的准入系统的一部分。
    于是我把这个注解去掉,发现还是相同的错误。
    那么可以判定不是这个注解的原因。
    于是我把jar包中的DataSyncServiceApi添加@Lazy 改为懒加载。
    这次能成功启动了,我再调用加了注解的方法,这个时候抛出了一个异常,具体内容为:
    interface ‘xxxxxxx’ is not visible from class loader
    提示这个接口在类加载器加载之后 是不可见的
    那是因为jar包中使用的类加载器和服务中使用的类加载器不同吗?
    这个服务的唯一特殊之处在于引入了准入的jar包,于是我根据依赖树,果然发现了一个模块Spring-boot-devtools,这是热部署模块,而这个模块的类加载器确实和普通的类加载器不同:
    一个RestartClassLoader,一个普通的AppClassLoader
    。。。。。
    由此也可以分析出,为什么不设置为懒加载时,会一直提示找不到DataSyncServiceApi,因为类加载器不同,不同的类加载器加载出来的文件互相不可见,此时jar包要使用服务中加载的类就无法获取到。
     
    解决方案:
    1.将jar包的类加载器改为热部署的类加载器
    2.服务中移除Spring-boot-devtools

  • 相关阅读:
    MySQL——SELECT
    启动 MySQL
    Ethernet and ARP 及Wireshark实验
    ICMP 协议及Wireshark实验
    Wireshark实验——IP 协议
    关键路径
    用树结构存储的图博客(笑)
    拓扑排序
    云计算部署的未来趋势将从自动化转向为自主化
    苹果拥抱 Rust,正在将 C 代码移植到 Rust
  • 原文地址:https://www.cnblogs.com/ymqj520/p/13627144.html
Copyright © 2011-2022 走看看