• 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包里面的commysqljdbcDriver.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:UsersIBM_ADMINPROJECTCrazyJAVAPROJECT_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的机制。

  • 相关阅读:
    rabbitMQ交换机的发布订阅模式
    Winforms平台界面开发技巧分享:增强的MVVM功能
    VCL分析工具DevExpress VCL全新发布v19.2.7
    Winforms界面开发v20.1——兼容.Net Core 5
    ASP.NET界面开发技巧放送,轻松自定义Grid运行时编辑表单布局
    现代Web开发堆栈工具DevExtreme 2020年首发v20.1.3
    Web界面开发工具!Kendo UI for jQuery数据管理:虚拟滚动
    Winforms平台界面开发技巧分享:Data Grid和Tree List悬停行外观
    现代Web开发堆栈工具DevExtreme——增强UI小部件功能
    界面控件套包DevExpress 2020年首发v20.1.3
  • 原文地址:https://www.cnblogs.com/fysola/p/6100961.html
Copyright © 2020-2023  润新知