JDBC驱动程序实现和类加载

时间:2016-09-04 16:57:18

标签: java mysql jdbc

不久前我正在实施JDBC驱动程序。但在开始工作之前,我已经研究了一些MySQL JDBC驱动程序源,发现它们包含var string1 = "hello any body from me"; var result = string1.split(" ").reverse()[0]; console.log(result); // me 接口的两个实现:com.mysql.jdbc.Drivercom.mysql.jdbc.NonRegisteringDriver,其中{{1} }还扩展了java.sql.Driver

Driver类只包含一个静态块,它调用NonRegisteringDriver来注册该类:

Driver

虽然DriverManager.registerDriver()实现了所有static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } 接口方法。

我的第一个想法是,通过以这种方式实现驱动程序,MySQL驱动程序的开发人员遵循java.sql.Driver指导说明如下:

  

强烈建议每个Driver类都应小而独立,以便可以加载和查询Driver类,而无需引入大量支持代码。

但是,如果我正确理解Java类加载,那么单独的NonRegisteringDriver类绝对没有意义,因为在执行静态块之前,所有实现代码的父级都将被加载。

我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:3)

不,实际上没有com.mysql.jdbc.Driver类的mysql JDBC驱动程序的实现将不满足java.sql.Driver协议,claims

  

加载Driver类时,应该创建一个实例   本身并使用DriverManager注册它。这意味着用户可以通过调用

来加载和注册驱动程序
Class.forName("foo.bah.Driver")}  

com.mysql.jdbc.NonRegisteringDriver类不包含创建自我实例并注册它的这一部分。

为什么mysql开发人员决定将实现本身与基本上注册其实例的类区分开来?很难说,但如果他们决定在同一个包中提供多个实现,它可能会很方便。然后,类com.mysql.jdbc.Driver将扩展默认值。

更新:事情就像我上面描述的那样。至少有3个派生类扩展com.mysql.jdbc.NonRegisteringDriver

  • com.mysql.jdbc.Driver
  • com.mysql.fabric.jdbc.FabricMySQLDriver
  • com.mysql.jdbc.NonRegisteringReplicationDriver

虽然com.mysql.jdbc.Driver是默认实现,但其他人会覆盖基类中的某些方法。如果NonRegisteringDriver将包含用于创建其实例并注册它的静态块,那么在内存中使用派生类就不可能只有一个所需的mysql驱动程序。

但总的来说,没有充分的理由。例如,org.postgresql.Driver实施contains本身就是java.sql.Driver的完整实施。