JVM Class Loader详解

classloader.png

    

    jvm一启动,就会开始做一些初始化的动作,之后就会产生一个BootStrapClassLoader,该ClassLoader由C++ native提供,他除了做一些基本的初始化,最重要的工作就是加载sun.misc.Launcher$ExtClassLoader,并设置其parent为null,接着加载sun.misc.Launcher$AppClassLoader,并将其parent设置为ExtClassLoader。

classloader.png

 下面看一段ClassLoader中loadclass方法源码

———————————————————————————————————

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
 {
  // First, check if the class has already been loaded
  Class c = findLoadedClass(name);
  if (c == null)
  {
   try
   {
    if (parent != null)
    {
     c = parent.loadClass(name, false);
    }
    else
    {
     c = findBootstrapClass0(name);
    }
   }
   catch (ClassNotFoundException e)
   {
    // If still not found, then invoke findClass in order
    // to find the class.
    c = findClass(name);
   }
  }
  if (resolve)
  {
   resolveClass(c);
  }
  return c;
 }

——————————————————————————————————

    通过以上源码,可以看到,ClassLoader会先看该类实行已经被加载,如果被加载则直接返回,否则去父加载器中查找,最后调用findClass方法查找该类,故如果我们想要实现自己的ClassLoader,关键点就在于重写findClass类。从此处联想到web应用中,web容器会去WEB-INF/classes下加载类,会去WEB-INF/lib下加载库,应该是web容器实现了WebAppClassLoader,并覆盖findClass方法,到指定路径下去寻找类库了。

    记起每次在web应用中调用Clazz.class.getClassLoader().getResource()去取得资源文件时的困扰,一直不理解。现在看来,getResource传入一个资源的相对路径,该路径是相对WebAppClassLoader的类加载跟路径而言的,若传入".",则得到的就是该WebAppClassLoader类加载器的根路径。

Leave a Reply

Your email address will not be published. Required fields are marked *

You must enable javascript to see captcha here!