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的機制。