load/find class 与 forname 在static代码块加载的不同 (二)非系统类jdbc

load/find class 与 forname 在static代码块加载的不同 上一篇说到:

既不用forName,又不用loadClass也可以;

经过JDBC SPI 类加载机制,我们发现,原来

DriverMagager的静态函数getConnection激发DriverManager的静态代码块,在其中
* 扫描当前线程类加载器中一切符合jdbc SPI规范的驱动类,然后加载并实例化

 

 一般当前线程类加载器即系统类加载器,那么我们把系统类加载器的mysql pom干掉:

    <!--<dependency>-->
      <!--<groupId>mysql</groupId>-->
      <!--<artifactId>mysql-connector-java</artifactId>-->
      <!--<version>5.1.29</version>-->
    <!--</dependency>

 

java.sql.SQLException: No suitable driver found for jdbc:mysql://127.0.0.1:53306/saturn?useUnicode=true&amp;characterEncoding=utf-8&useSSL=false
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at lc.JdbcUtilNonSysLoader.main(JdbcUtilNonSysLoader.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Exception in thread "main" java.lang.NullPointerException
at lc.JdbcUtilNonSysLoader.main(JdbcUtilNonSysLoader.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

 

然后把jdbcdriver放到自定义加载器中,再来试验forName还是loadClass;我们找上了JDBC注册原理与自定义类加载器解决com.cloudera.hive.jdbc41.HS2Driver的加载【重点】中3.3的例子,很像,pom及系统类加载器下没有mysql driver,自定义加载器加载driver,使用proxy绕开jdbc检查机制,现在我们看一下forName和loadClass,原文是使用forName的,我们看下loadCLass:

 

结论:loadClass+实例化=forName效果,与load/find class 与 forname 在static代码块加载的不同中结论相同

 

posted on 2020-03-06 12:42  silyvin  阅读(200)  评论(0编辑  收藏  举报