标签:静态代码块 dcl 路径 机制 替换 lib 面向接口编程 -- 方式
名称 | 加载哪的类 | 说明 |
---|---|---|
BootStrap ClassLoader(启动类加载器) | JAVA_HOME/jre/lib | 无法直接访问(C++代码书写的) |
Extension ClassLoader(扩展类加载器) | JAVA_HOME/jre/lib/ext | 上级为BookStrap,显示为null |
Application ClassLoader(应用程序类加载器) | classpath | 上级为Extension |
自定义类加载 | 自定义 | 上级为Application |
总体思想:委派上级优先做类的加载,上级没有此类,再由本级的类加载器进行加载
执行流程:
调用本类的classLoad方法:
先检测该类在本类加载器中是否已加载(findLoadedClass(name)),
若没有,再判断此加载器是否存在上级。
若有上级,委派上级:调用上级类加载器的classLoad方法;
若不存在上级,证明此类加载器为扩展类加载器,则调用findBootstraporNull(name)方法来完成类的查找
若所有的上级都没有找到此类;
则在本级查找此类,找到:本类加载器调用findClass(name)方法(每个类加载器自己扩展的)来加载这个类。找不到:抛出类找不到异常。
注意:
前提:在使用jdbc时,要加载Driver驱动(Class.forName("com.mysql.jdbc.Driver")),不写它时,此驱动也是会被正常加载的。
问题提出:DriverManager(java.sql.DriverManager)是启动类路径下的,故它的类加载器是Bookstrap ClassLoader,会到JAVA_HOME/jre/lib下搜索类,显然此路径下是没有mysql-connector-java-5.1.48.jar包的。
那DriverManager在静态代码块中怎样正确的加载com.mysql.jdbc.Driver呢?
加载方法:
打破了双亲委派的模式,使用应用程序类加载器启动类的加载
体现了面向接口编程+解耦的思想
注:线程上下文类加载器是当前线程使用的类加载器,
在线程启动时,由jvm默认将应用程序类加载器赋值给当前线程。
标签:静态代码块 dcl 路径 机制 替换 lib 面向接口编程 -- 方式
原文地址:https://www.cnblogs.com/ekig/p/14933368.html