• 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

  • 相关阅读:
    使用ZeroMQ(clrzmq)实现异步通信
    WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码(一)概要设计
    .net 数据缓存(二)之Redis部署
    .net 数据缓存(一)之介绍
    如果css足够强大了,你还会用编程的方式实现去实现css已有的功能吗?
    我想做一个合格的工程师
    当新手使用JS库遇到问题怎么办
    JS(JavaScript)脚本库的积累
    ASP.NET MVC 必备开发环境
    z-albert之开启博文之路
  • 原文地址:https://www.cnblogs.com/ymqj520/p/13627144.html
Copyright © 2020-2023  润新知