前几天写一个dubbo项目,需要用到dubbo的filter和一个定时任务task,两个地方都会调用一个静态list,filter给list增加元素,task读取list,但是运行的时候发现不管filter怎么给list加元素,task读取到的list永远为空。
debug发现filter的list一直在增长,task获取到的list的size一直是0,还发现这两个list对象id不一样,这就很奇怪了,这个list明明是个static变量,不存在是两个对象的情况,然后想到,这两个对象不一样,会不会这两个类就不是同一个?
于是在filter和task里调用Util.class,发现类的全限定名是一样的,但是它们的类加载器不一样。我们知道,jvm判断两个类是否是同一个的方法,有两方面:
一是判断全限定名;
二是判断是否是同一个类加载器加载的;
所以判定两个类不是同一个,那么里面的list也肯定不是同一个。
我们再看看这个类加载器,一个是appclassloader,这个我们都知道是系统类加载器,一般我们的应用程序的类都是它加载的;
另一个是RestartClassLoader,这个是springboot热部署jar包提供类,使用热部署功能,项目启动的时候项目的类都会被它加载,引用jar包的除外。
我们知道dubbo的filter是通过spi机制实例化的,它是使用appclassloader加载的,所以task和filter都使用了util,但是却不是同一个类。
解决方法很简单,不使用spring-boot-devtools。