標籤:
轉載自http://blog.csdn.net/mousebaby808/article/details/31788325
概述 諸如tomcat這樣的伺服器,在啟動的時候會載入應用程式中lib目錄下的jar檔案以及classes目錄下的class檔案,另外像spring這類架構,也可以根據指定的路徑掃描並載入指定的類檔案,這個技術可以實現一個容器,容納各類不同的子應用。 Java類由於需要載入和編譯位元組碼,動態載入class檔案較為麻煩,不像C載入動態連結程式庫只要一個檔案名稱就可以搞定,但JDK仍提供了一整套方法來動態載入jar檔案和class檔案。 動態載入jar檔案
[java] view plaincopy
- // 系統類別庫路徑
- File libPath = new File(jar檔案所在路徑);
-
- // 擷取所有的.jar和.zip檔案
- File[] jarFiles = libPath.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".jar") || name.endsWith(".zip");
- }
- });
-
- if (jarFiles != null) {
- // 從URLClassLoader類中擷取類所在檔案夾的方法
- // 對於jar檔案,可以理解為一個存放class檔案的檔案夾
- Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
- boolean accessible = method.isAccessible(); // 擷取方法的存取權限
- try {
- if (accessible == false) {
- method.setAccessible(true); // 設定方法的存取權限
- }
- // 擷取系統類別載入器
- URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
- for (File file : jarFiles) {
- URL url = file.toURI().toURL();
- try {
- method.invoke(classLoader, url);
- LOG.debug("讀取jar檔案[name={}]", file.getName());
- } catch (Exception e) {
- LOG.error("讀取jar檔案[name={}]失敗", file.getName());
- }
- }
- } finally {
- method.setAccessible(accessible);
- }
- }
動態載入class檔案
[java] view plaincopy
- // 設定class檔案所在根路徑
- // 例如/usr/java/classes下有一個test.App類,則/usr/java/classes即這個類的根路徑,而.class檔案的實際位置是/usr/java/classes/test/App.class
- File clazzPath = new File(class檔案所在根路徑);
-
- // 記錄載入.class檔案的數量
- int clazzCount = 0;
-
- if (clazzPath.exists() && clazzPath.isDirectory()) {
- // 擷取路徑長度
- int clazzPathLen = clazzPath.getAbsolutePath().length() + 1;
-
- Stack<File> stack = new Stack<>();
- stack.push(clazzPath);
-
- // 遍曆類路徑
- while (stack.isEmpty() == false) {
- File path = stack.pop();
- File[] classFiles = path.listFiles(new FileFilter() {
- public boolean accept(File pathname) {
- return pathname.isDirectory() || pathname.getName().endsWith(".class");
- }
- });
- for (File subFile : classFiles) {
- if (subFile.isDirectory()) {
- stack.push(subFile);
- } else {
- if (clazzCount++ == 0) {
- Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
- boolean accessible = method.isAccessible();
- try {
- if (accessible == false) {
- method.setAccessible(true);
- }
- // 設定類載入器
- URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
- // 將當前類路徑加入到類載入器中
- method.invoke(classLoader, clazzPath.toURI().toURL());
- } finally {
- method.setAccessible(accessible);
- }
- }
- // 檔案名稱
- String className = subFile.getAbsolutePath();
- className = className.substring(clazzPathLen, className.length() - 6);
- className = className.replace(File.separatorChar, ‘.‘);
- // 載入Class類
- Class.forName(className);
- LOG.debug("讀取應用程式類檔案[class={}]", className);
- }
- }
- }
- }
完成上述兩步操作後,即可使用Class.forName來載入jar中或.class檔案包含的Java類了。
[轉載] Java中動態載入jar檔案和class檔案