1
sawyera 2020-05-10 21:46:05 +08:00 1
先说结论:Class.forName 遵循双亲委派机制
参考: Class.forName 方法: @CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { Class<?> caller = Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); } 可以看出是使用 ClassLoader.getClassLoader(caller) 类加载器进行加载的,默认是使用的用户类加载器,还是符合双亲委派机制的。 如有错误,请指出 |
2
isir1234 2020-05-11 11:43:26 +08:00 1
为什么必须要破坏?::
DriverManager::getConnection 方法需要根据参数传进来的 url 从所有已经加载过的 Drivers 里找到一个合适的 Driver 实现类去连接数据库. Driver 实现类在第三方 jar 里, 要用 AppClassLoader 加载. 而 DriverManager 是 rt.jar 里的类, 被 BootstrapClassLoader 加载, DriverManager 没法用 BootstrapClassLoader 去加载 Driver 实现类, 所以只能破坏双亲委派模型, 用它下级的 AppClassLoader 去加载 Driver. 如何破坏的?:: > SPI 机制 Driver 具体的实现类 jar 包在 META-INF/services/java.sql.Driver 文件里写上自己 Driver 实现类的全限定名, 比如 `org.postgresql.Driver` , JDK8 的 DriverManager 在 static 代码块里(JDK14 是在第一次 getConnection 时)会用 ServiceLoader 获取所有的 Driver 并使用 Thread.currentThread().getContextClassLoader() 获取到的 AppClassLoader 加载该类, Driver 实现类的 static 代码块会去调用 DriverManager::registerDriver 将自己注册到 DriverManager 里. 个人理解... |