本文主要是介绍Tomcat 违背双亲委派模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Tomcat 违背双亲委派模式
【Tomcat 类加载机制】:
双亲委派模型要求除了顶层的启动类加载器之外,其余的类加载器都应当由自己的父类加载器加载。
CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。
WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。
【违背双亲委派】: tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器。例如:如果tomcat 的 Common ClassLoader 想加载 WebApp ClassLoader 中的类,该怎么办?我们可以使用线程上下文类加载器实现,使用线程上下文加载器,可以让父类加载器请求子类加载器去完成类加载的动作。
【违背双亲委派三个方面】:(1)向前兼容;(2)加载SPI接口实现类;(3)热部署
【Tomcat类加载过程】:
tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类(Object,String等),各个web应用自己的类加载器(WebAppClassLoader)会优先加载,加载不到时再交给commonClassLoader走双亲委托。具体的加载逻辑位于WebAppClassLoaderBase.loadClass()
方法中,这里以文字描述加载一个类过程:
- 先在本地缓存中查找是否已经加载过该类(对于一些已经加载了的类,会被缓存在
resourceEntries
这个数据结构中),如果已经加载即返回,否则 继续下一步。 - 让系统类加载器(AppClassLoader)尝试加载该类,主要是为了防止一些基础类会被web中的类覆盖,如果加载到即返回,返回继续。
- 前两步均没加载到目标类,那么web应用的类加载器将自行加载,如果加载到则返回,否则继续下一步。
- 最后还是加载不到的话,则委托父类加载器(Common ClassLoader)去加载。
第3第4两个步骤的顺序已经违反了双亲委托机制,除了tomcat之外,JDBC,JNDI,Thread.currentThread().setContextClassLoader();
等很多地方都一样是违反了双亲委托。
【参考文献】:Tomcat类加载器破坏双亲委派
tomcat学习步骤,附带打破双亲委派模型企业应用实战
深入理解 Tomcat(四)Tomcat 类加载器之为何违背双亲委派模型
这篇关于Tomcat 违背双亲委派模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!