java不同包中含有全限定类名相同的类时的加载顺序

如果有两个不同的jar包中含有两个全限定类名完全相同的类,那么如果我们程序中使用到了这个类,会加载哪一个呢,今天我们就来做个试验看看。

为了做试验,我们建立如下三个module,其中main是一个springboot项目,其中引用了demo1和demo2两个模块。如下图

 

demo1和demo2中都有一个com.demo.DemoClass类,如下:

 

然后我们在main类中写一个接口,访问com.demo.DemoClass中的info字段,如下。

 

好了,启动项目,访问/test接口,可以看到,我们加载到的是demo1中的DemoClass。

 

接下来我们做一点改变,把maven中的依赖换个顺序,demo1放下面,如下

 

再次启动,访问/test,可以看到我们加载到的是demo2中的DemoClass。说明我们访问到的类和在maven中的依赖顺序有关。

 

以为这就完了?no no no !

我们接着做试验,这次我们把我们的springboot项目打成war包,部署到tomcat看一下。

如下图是把我们的项目部署到tomcat,可以看到我们的demo1和demo2两个依赖,启动tomcat访问一下/test,这里就不截图了,和上面结果图差不多,但是结论不一样,结论就是无论我们maven依赖顺序如何,访问到的始终是demo1中的DemoClass。

 

这里我们再做个试验,把demo1-1.0-SNAPSHOT.jar,重新命名为demo3-1.0-SNAPSHOT.jar,注意此时demo3排在了demo2下面,这一点很重要(注意demo3-1.0-SNAPSHOT.jar中的info字段仍然是"demo1中的DemoClass"),此时我们再重启tomcat访问,结论是这次加载到的是demo2中的DemoClass。

通过以上试验可以看出,springboot jar包方式运行时,加载类时是按照maven中的依赖顺序进行加载的,如果已经加载过某个类,则后依赖的jar包中有全限定类名相同的类时是不会被加载到的。但是在tomcat中,加载类的顺序是按照jar包在操作系统中的文件排序进行的(这里的文件排序不确定一定是文件名,不同操作系统文件排序规则可能不一样),在多个jar包中有全限定类名相同的类的情况下,jar文件排序靠前的会被优先加载到。

为什么springboot就能保证按maven中的顺序加载呢?我们打开springboot打的jar包,可以看到jar包中有个classpath.idx,打开这个文件可以看到里面明确定义了各jar包的加载顺序,所以能够按照我们在maven中定义顺序来加载。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章