当前位置:   article > 正文

从源码级深入剖析Tomcat类加载原理_tomcat 类加载器

tomcat 类加载器

众所周知,Java中默认的类加载器是以父子关系存在的,实现了双亲委派机制进行类的加载,在前文中,我们提到了,双亲委派机制的设计是为了保证类的唯一性,这意味着在同一个JVM中是不能加载相同类库的不同版本的类。
然而与许多服务器应用程序一样,Tomcat 允许容器的不同部分以及在容器上运行的不同Web应用程序可以访问的各种不同版本的类库,这就要求Tomcat必须打破这种双亲委派机制,通过实现自定义的类加载器(即实现了java.lang.ClassLoader)进行类的加载。下面,就让我们来看看Tomcat类加载原理是怎样的。

Tomcat中有两个最重要的类加载器,第一个便是负责Web应用程序类加载的WebappClassLoader,另一个便是JSP Servlet类加载器`JasperLoader。

Web应用程序类加载器(WebappClassLoader)

上代码:

  1. public class WebappClassLoader extends WebappClassLoaderBase {
  2. public WebappClassLoader() {
  3. super();
  4. }
  5. public WebappClassLoader(ClassLoader parent) {
  6. super(parent);
  7. }
  8. ...
  9. }

我们来看看WebappClassLoader继承的WebappClassLoaderBase中实现的类加载方法loadClass

  1. public abstract class WebappClassLoaderBase extends URLClassLoader
  2. implements Lifecycle, InstrumentableClassLoader, WebappProperties, PermissionCheck {
  3. ... 省略不需要关注的代码
  4. protected WebappClassLoaderBase() {
  5. super(new URL[0]);
  6. // 获取当前WebappClassLoader的父加载器系统类加载器
  7. ClassLoader p = getParent();
  8. if (p == null) {
  9. p = getSystemClassLoader();
  10. }
  11. this.parent = p;
  12. // javaseClassLoader变量经过以下代码的执行,
  13. // 得到的是扩展类加载器(ExtClassLoader)
  14. ClassLoader j = String.class.getClassLoader();
  15. if (j == null) {
  16. j = getSystemClassLoader();
  17. while (j.getParent() != null) {
  18. j = j.getParent();
  19. }
  20. }
  21. this.javaseClassLoader = j;
  22. securityManager = System.getSecurityManager();
  23. if (securityManager != null) {
  24. refreshPolicy();
  25. }
  26. }
  27. ...省略不需要关注的代码
  28. @Override
  29. public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
  30. synchronized (getClassLoadingLock(name)) {
  31. if (log.isDebugEnabled()) {
  32. log.debug("loadClass(" + name + ", " + resolve + ")");
  33. }
  34. Class<?> clazz = null;
  35. // Web应用程序停止状态时,不允许加载新的类
  36. checkStateForClassLoading(name);
  37. // 如果之前加载过该类,就可以从Web应用程序类加载器本地类缓存中查找,
  38. // 如果找到说明WebappClassLoader之前已经加载过这个类
  39. clazz = findLoadedClass0(name);
  40. if (clazz != null) {
  41. if (log.isDebugEnabled()) {
  42. log.debug(" Returning class from cache");
  43. }
  44. if (resolve) {
  45. resolveClass(clazz);
  46. }
  47. return clazz;
  48. }
  49. // Web应用程序本地类缓存中没有,可以从系统类加载器缓存中查找,
  50. // 如果找到说明AppClassLoader之前已经加载过这个类
  51. clazz = findLoadedClass(name);
  52. if (clazz != null) {
  53. if (log.isDebugEnabled()) {
  54. log.debug(" Returning class from cache");
  55. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/500765
推荐阅读
相关标签
  

闽ICP备14008679号