關於JAVA ClassLoarder機制與一個示例

ClassLoader

這個你們熟悉,加載機制,雙親委派。
JAVA啓動時,會初始化3個類加載器,BootClassLoader,ExtClassLoader,AppClassLoader。
BootClassLoader 加載jre/lib下的JAR包,由C++實現。 ExtClassLoader 加載jre/lib/ext下的JAR包,其父加載器爲BootClassLoader。 AppClassLoader 加載classpath下的JAR包,也稱用戶加載器。其父加載器爲ExtClassLoader。java

示例

經常使用的自定義類加載器爲tomcat,spring-boot會有本身的類加器。 咱們如今本身實一個類加載器,從e:/arthas目錄下加載class。類加載器除了加載Class還有一個主要功能,那就是加載資源。這裏咱們簡單一點,直接繼承URLClassLoader。若是要本身作的話,那就繼承ClassLoader,而後重寫findClass和findResource方法。spring

調用類B.java

public class B {


    public static void main(String[] args) throws InterruptedException {
        FileClassLoad fileClassLoad = new FileClassLoad();
        try {
            Class clazz = fileClassLoad.loadClass("spring.B1");
            System.out.println(clazz);
            clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }
	}

兩個測試類B1.java B2.java

public class B1 {
   
   public B1(){
       
       B2 b2 = new B2();
       b2.say();
   }
   
}
public class B2 {

   public void say(){
       URL url = this.getClass().getResource("test.txt");
       System.out.println(url);
       System.out.println(B2.class.getClassLoader());
   }
}

FileClassLoader自定義加載器

public class FileClassLoad extends URLClassLoader {

    private static  URL[] urls = null;

    static{
        try {
            File file = new File("E://arthas/");
            urls = new URL[1];
            urls[0]=file.toURI().toURL();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println(name);
        return super.findClass(name);
    }

    public FileClassLoad(){
        super(urls);
    }
}

編譯,將它從class目錄下移除,若是不移除的話,執行後,不會用到咱們的自定義加載器,那test.txt將會獲取不到。這就是雙親,先從父加載器加載,父加載器加載不到,再從當前加載器進行加載。
將B1.class B2.class按包結構考備到e:/arthas目錄下,而且建立test.txt。 運行,結果以下:tomcat

spring.B1
class spring.B1
spring.B2
file:/E:/arthas/spring/test.txt   //經過FileClassLoader加載的資源
spring.FileClassLoad@5b2133b1    //B2.class 採用的是咱們自定義的加載器,這裏是委派,用B1的加載器加載B2

有了這些基礎再去看spring-boot的類加載器,就比較方便了。另外spring-boot會什麼要用本身的類加載器。答案很簡單。spring-boot打出來的JAR裏面包含boot-info目錄,在該目錄下還有jar包和class。spring-boot自定義加載器就是須要加載該目錄下的JAR和資源。同裏tomcat也是,它也有本身特定格式下的資源,好比war包。ide

相關文章
相關標籤/搜索