java掃描某個包下的所有java類並加載


  最近在學習java的反射和注解,實際情景中需要掃描某個包下的所有java類,然后使用類加載器加載類。

  基本思路,獲得程序的路徑掃描src下某個包內的子包和java類,實現也比較簡單。

  運行環境:windows10+jdk1.8+eclipse

  直接貼代碼

  

package org.test.scanner;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/*
 * date:2019-07-23
 * */
public class PackageScanner {
    private List<Class<?>> classes;
    private String packagePath = null;

    /*
     * 無參構造方法,內部調用帶參的構造方法。
     * 
     * @throw classNotFound
     * 
     */
    public PackageScanner() throws ClassNotFoundException {
        this("");
    }

    /*
     * 實現,調用fileScanner進行目錄掃描和加載
     * 
     * @param String 傳入需要掃描的包
     * 
     * @throw classNotFound
     */
    public PackageScanner(String basePackage) throws ClassNotFoundException {
        packagePath = System.getProperty("user.dir") + "\\src\\";
        String filePath = packagePath + basePackage.replace('.', '\\');
        classes = new ArrayList<Class<?>>();
        fileScanner(new File(filePath));
    }

    private void fileScanner(File file) throws ClassNotFoundException {
        if (file.isFile() && file.getName().lastIndexOf(".java") == file.getName().length() - 5) {//5是".java"的長度
            String filePath = file.getAbsolutePath();
            String qualifiedName = filePath.substring(packagePath.length(), filePath.length() - 5).replace('\\', '.');
            System.out.println(qualifiedName);
            classes.add(Class.forName(qualifiedName));
            return;
        } else if (file.isDirectory()) {
            for (File f : file.listFiles())
                fileScanner(f);
        }
    }

    /*
     * 得到加載到的類對象的List,返回的是ArrayList
     */
    public List<Class<?>> getClasses() {
        return this.classes;
    }
}

  

這是一個簡單的包掃描類,這里直接使用Class.forName()加載掃描到的類

我們可以看一下forName實現

 

public static Class<?> forName(String className) throws ClassNotFoundException {
	return forName0(className, true, ClassLoader.getCallerClassLoader());
	}

 

發現調用了ClassLoader.getCallerClassLoader() 

從名字上可以看出是得到調用類的類加載器,我們可以看一下它的實現

 

static ClassLoader getCallerClassLoader() {
		// NOTE use of more generic Reflection.getCallerClass()
		Class caller = Reflection.getCallerClass(3);
		// This can be null if the VM is requesting it
		if (caller == null) {
			return null;
		}
		return caller.getClassLoader0();
	}

 

關鍵一句: Reflection.getCallerClass(3)。

一直往上傳遞,直到獲取到它的調用類,然后得到調用類的類加載器


其中 REflection.getCallerClass()的參數有:

0 和小於0  -   返回 Reflection類 

1  -   返回自己的類 

2  -    返回調用者的類 
3. 4. ....層層上傳。

 

最后的目的就是誰調用這個類,調用類的類加載器就負責加載這個類。只有當它的加載類為null時,即沒有任何加載器可用時,才使用getClassLoader0()這個native方法,這是啟動類加載器的實現方法,如果不是java lib目錄里的庫,該類是不會被加載的。

 

通過學習java 的包掃描和類加載,我簡單的了解了java類加載器的用法。

能力有限,如有錯誤請告知一聲。

 

 

ps:學而不思則罔,思而不學則殆。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM