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

  • 相关阅读:
    windows配置solr5.5.2(不通过tomcat,使用内置jetty)
    6月8日云栖精选夜读:mac下eclipse配置tomcat无法启动问题
    零配置部署 React
    万亿级数据洪峰下的分布式消息引擎
    ENode 2.0
    WannaCry感染文件恢复方法_企业再也不用愁了!
    中国最强的人工智能学术会议来了
    1篇文章看懂峰值带宽、流量、转码、连麦、截图五大直播计费方式
    CSS基础(三)
    CSS基础(三)
  • 原文地址:https://www.cnblogs.com/ymqj520/p/13627144.html
Copyright © 2011-2022 走看看