JAVA基礎知識之JVM-——URLClassLoader


URLClassLoader是ClassLoader的一個實現類,它既能從本地加載二進制文件類,也可以從遠程加載類。

它有兩個構造函數, 即 

URLClassLoader(URL[] urls),使用默認的父類加載器(SystemClassLoader)創建一個ClassLoader對象

URLClassLoader(URL[] urls, ClassLoader parent),使用指定的類加載器作為父類加載器創建ClassLoader對象

上面兩個構造函數都有一個URL參數,這里的URL參數值可以是file:前綴,http:前綴,也可以是ftp:前綴,功能非常強大。

下面的例子中,我將用URLClassLoader加載mysql的驅動包,通過loadClass加載指定的類,進而通過newInstance創建該類默認實例,得到com.mysql.jdbc.Driver對象。

 1 package jvmTest;
 2 
 3 import java.net.URL;
 4 import java.net.URLClassLoader;
 5 import java.sql.Connection;
 6 import java.sql.Driver;
 7 import java.util.Properties;
 8 
 9 public class URLClassLoaderTest {
10     private static Connection conn;
11     
12     public static Connection getConn(String url, String user, String pass) throws Exception {
13         if (conn == null) {
14             //創建URL數組
15             URL[] urls = {new URL("file:mysql-connector-java-5.1.12-bin.jar")};
16             //以默認的ClassLoader作為父類的ClassLoader, 創建URLClassLoader
17             URLClassLoader myClassLoader = new URLClassLoader(urls);
18             System.out.println("默認父類加載器: " + myClassLoader.getParent());
19             System.out.println("默認父類加載器路徑: " + myClassLoader.getParent().getResource(""));
20             System.out.println("當前的類加載器路徑: " + myClassLoader.getResource(""));
21             
22             //加載 mysql-connector-java-5.1.12-bin.jar包里面的\com\mysql\jdbc\Driver.class 驅動,並創建實例
23             //加載路徑 myClassLoader.getResource("")
24             Driver driver =  (Driver)myClassLoader.loadClass("com.mysql.jdbc.Driver").newInstance();
25             //創建一個設置jdbc連接屬性的Properties對象
26             Properties props = new Properties();
27             props.setProperty("user", user);
28             props.setProperty("password", pass);
29             //調用driver的connection來取得連接
30             conn = driver.connect(url, props);
31         }
32         return conn;
33     }
34     
35 
36     
37     public static void main(String[] args) throws Exception {
38         System.out.println("user.dir: " + System.getProperty("user.dir"));
39         System.out.println(getConn("jdbc:mysql://localhost:3306/mysql", "root", ""));
40     }
41 }

將mysql驅動包mysql-connector-java-5.1.12-bin.jar放在系統類加載器的路徑下,即file:/C:/Users/IBM_ADMIN/PROJECT/CrazyJAVA/PROJECT_JavaBasic/bin/

容納后在Eclipse中執行這個程序,會發現拋出錯誤,

 1 user.dir: C:\Users\IBM_ADMIN\PROJECT\CrazyJAVA\PROJECT_JavaBasic
 2 默認父類加載器: sun.misc.Launcher$AppClassLoader@556e8bda
 3 默認父類加載器路徑: file:/C:/Users/IBM_ADMIN/PROJECT/CrazyJAVA/PROJECT_JavaBasic/bin/
 4 當前的類加載器路徑: file:/C:/Users/IBM_ADMIN/PROJECT/CrazyJAVA/PROJECT_JavaBasic/bin/
 5 Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
 6     at java.net.URLClassLoader.findClass(URLClassLoader.java:600)
 7     at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:777)
 8     at java.lang.ClassLoader.loadClass(ClassLoader.java:750)
 9     at java.lang.ClassLoader.loadClass(ClassLoader.java:731)
10     at jvmTest.URLClassLoaderTest.getConn(URLClassLoaderTest.java:24)
11     at jvmTest.URLClassLoaderTest.main(URLClassLoaderTest.java:39)

報ClassNotFoundException,感覺很奇怪,明明驅動包就在加載路徑下面。。。

於是再在cmd窗口中執行這個程序,卻能正常執行,

對於這個問題,自己研究了下,也百度了一下,初步認定是Eclipse執行java程序的時候,會使用Eclipse的classpath設置,而不是使用操作系統的classpath,

經過測試,Eclipse似乎是用的是工作目錄(user.dir)作為classpath。

不過上面的錯誤並不是重點,重點是演示URLClassLoader的機制。

 


免責聲明!

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



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