类的双亲委派机制
启动类加载器Bootstrap ClassLoader -> lib
扩展类加载器Extension ClassLoader -> ext
应用程序类加载器 Application ClassLoader
- 防止重复加载
原因
无法实现隔离性
如果使用默认的类加载器机制,那么是无法加载两个相同类库的不同版本,默认类加载器是不管你是什么版本的,只在乎你的全限类名,并且只有一份。一个web容器可能要部署两个或者多个应用程序,可能会依赖同一个第三方类库的不同版本,因为要保证每一个应用程序的类库都是独立的、相互隔离的。部署在同一个web容器中的相同类库的相同版本可以共享,否则,会有重复的类库被加载进JVM,web容器也有自己的类库,不能和应用程序的类库混淆,需要相互隔离。无法实现热替换
jsp文件其实也是class文件,如果修改了,但是类名还是一样,类加载器会直接取方法区中已经存在的,修改后的jsp是不会重新加载的。
打破双亲委派机制OSGI 是基于Java语言的动态模板化规范,类加载器之间是网状结构,更加灵活,也更加复杂。tomcat的自定义类加载器
CommonClassLoader
最基本的类加载器,加载路径中的class可以被tomcat和各个webapp访问CatalinaClassLoader
tomcat私有类加载器,webapp不能访问其加载路径下的class, 对webapp不可见ShareClassLoader
各个webapp共享的类加载器,对tomcat不可见WebappClassLoader
webapp私有的类加载器,只对当前webapp可见。
每一个web应用程序对应一个webappClassLoader, 每一个jsp文件对应一个JspClassLoader, 所以这两个类加载器有多个实例
工作原理
- CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公共类库的公用。
- CatalinaClassLoader和SharedClassLoader自己能加载的类则与对方互相隔离
- WebappClassloader可以使用SharedClassLoader加载到的类,但各个webappClassLoader实例相互隔离,多个webappClassLoader是同级关系
- JasperClassLoader的加载范围仅仅是这个JSP文件编译出来的一个.Class文件,它出现的目的就是为了被废弃;当web容器检测到JSP文件被修改时,会替换成目前的JasperLoader的实例,并通过再建立一个新的JSP类加载器来实现JSP文件的HotSwap功能