不久前,我还在实现JDBC驱动程序。但在开始工作之前,我研究了一些MySQL JDBC驱动源,发现它们包含两个java.sql.Driver接口的实现:com.mysql.jdbc.Drivercom.mysql.jdbc.NonRegisteringDriver,其中Driver也扩展了NonRegisteringDriver
Driver类只包含调用DriverManager.registerDriver()来注册类的静态块:

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

NonRegisteringDriver实现了所有的java.sql.Driver接口方法。
我的第一个想法是,通过这样实现一个驱动程序,MySQL驱动程序的开发人员正在遵循java.sql.Driverguidlines,该guidlines声明如下:
强烈建议每个驱动程序类都应该小而独立,这样就可以加载和查询驱动程序类,而不必引入大量的支持代码。
但是,如果我正确理解Java类加载,那么拥有单独的com.mysql.jdbc.Driver类绝对没有意义,因为它的父类和所有实现代码都将在执行静态块之前加载。
我是不是丢了什么东西?

最佳答案

不,实际上如果没有com.mysql.jdbc.Driver类,JDBC驱动程序的当前实现将不能满足mysql协议,这claims
加载驱动程序类时,它应创建
自己注册给司机经理。这意味着用户可以通过调用

Class.forName("foo.bah.Driver")}

java.sql.Driver类不包含创建和注册自实例的这一部分。
为什么com.mysql.jdbc.NonRegisteringDriver开发人员决定将实现本身与本质上注册其实例的类区分开来?很难说清楚,但如果他们决定在同一个包中提供多个实现,这可能会很方便。然后类将扩展默认值。
更新:本质上的事情是如我上面所描述的。至少有3个派生类扩展了mysql
com.mysql.jdbc.Driver驱动程序
com.mysql.fabric.jdbc.FabricMySQLDriver
com.mysql.jdbc.NonRegisteringReplicationDriver
虽然com.mysql.jdbc.Driver是默认实现,但其他方法重写基类中的某些方法。如果com.mysql.jdbc.NonRegisteringDriver包含用于创建其实例并注册它的静态块,那么在内存中就不可能有一个所需的带有派生类的com.mysql.jdbc.Driver驱动程序。
但总的来说,这并没有强有力的理由。例如NonRegisteringDriver实现contains完全实现mysql本身。

07-25 22:53
查看更多