关于 深入理解Java虚拟机 书中 9.2.1中提出的问题

 2019-12-22 11:01  阅读(1140)
文章分类:JVM

问题:
如果有10个WEB应用程序都是用Spring来进行组织和管理的话,可以把Spring放到Common或Shared目录下(Tomcat5.0)让这些程序共享。Spring要对用户程序的类进行管理,自然要能访问到用户程序的类,而用户的程序显然是放在/WebApp/WEB-INF目录下的,那么被CommonClassLoader或SharedClassLoader加载的Spring如何访问并不在其加载范围内的用户程序呢?如果读过本书第7章的相关内容,相信读者可以很同意的回答这个问题。

我所理解的答案:
在书中的第7章的7.4.3说的是破坏双亲委派模型中的线程上下文类加载器即为答案。

先来说一下什么是“双亲委派模型”?
官方(书中)给出的答案为:双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。
(其实很好理解的,”顶层的启动类”就类似于Object类,在Java中,除了它没有父类以外,别的类都有父类。)

2019120001483\_1.png

遵循这个原则的好处就是,类加载器也有了层级,无论哪一种类加载器要加载一个类(Class),它都会去看一下他的上一层级类加载器,一直到找到最顶端的类加载器去加载,如果没有,才会自己加载,要不然一个加载器加载一个,很多重复的类就会乱了。
(原因和Object类必须唯一是一个道理的,一个程序中只能有一个Object类,然后才能让其它的类继承他,不唯一程序就乱了)
这里所说的最顶端的类加载器是指自定义类加载器那一层,上面的三个是系统提供的类加载器。

ok,这个模型真好啊!但是用着用着大家就发现问题了,因为自定义类加载器是从应用程序类加载器分支来的,而且他们还都是顶层了,那么证明他们各自就是独立的了,真好,但是,有那么一些情况,我不希望他们那么独立,因为有的时候需要你调用我,我调用你呀?

所以就有了另一种模式:破坏双亲委派模型。
这里我觉得题目中应该对应到的是书中所提到的第二次被破坏。是怎样破坏的呢?
书中是这样说的:
线程上下文类加载器可以通过java.lang.Thread类的setContextClassLoader()方法进行设置,如果创建线程时还未设置,它将会从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那这个类加载器就默认是应用程序类加载器。
也就相当于父类加载器请求子类加载器去完成类加载的动作。

哦??刚好违背了上面的子类找父类,父类没有,再子类自己加载;而现在,当前线程没设置哪个加载器,那就去父线程找,还没有,就直接是应用程序类加载器了,看上面的图,这个类加载器可是所有自定义类加载器的父类,那么,你在他这里岂不就是想调用谁就调用谁了!

我觉得我说明白了,哈哈哈!
如有不对欢迎指正!

点赞(1)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 关于 深入理解Java虚拟机 书中 9.2.1中提出的问题

相关推荐