DbUtils源码分析系列(三)

来源:互联网 发布:mac破解软件安装 编辑:程序博客网 时间:2024/06/06 06:38

今天分析一下DbUtils类。类图如下:

这里写图片描述
从类图中很容易看出DbUtils类提供了一些静态工具方法,方便JDBC操作。根据方法名可以明显看出方法的作用。
这里值得分析的方法是loadDriver方法。根据驱动类名,使用DbUtils的类加载器加载驱动,并返回加载是否成功标志。

  /**     * Loads and registers a database driver class.     * If this succeeds, it returns true, else it returns false.     *     * @param driverClassName of driver to load     * @return boolean <code>true</code> if the driver was found, otherwise <code>false</code>     */    public static boolean loadDriver(String driverClassName) {        return loadDriver(DbUtils.class.getClassLoader(), driverClassName);    }

它有一个重载方法:

/**     * Loads and registers a database driver class.     * If this succeeds, it returns true, else it returns false.     *     * @param classLoader the class loader used to load the driver class     * @param driverClassName of driver to load     * @return boolean <code>true</code> if the driver was found, otherwise <code>false</code>     * @since 1.4     */    public static boolean loadDriver(ClassLoader classLoader, String driverClassName) {        try {            Class<?> loadedClass = classLoader.loadClass(driverClassName);            if (!Driver.class.isAssignableFrom(loadedClass)) {                return false;            }            @SuppressWarnings("unchecked") // guarded by previous check            Class<Driver> driverClass = (Class<Driver>) loadedClass;            Constructor<Driver> driverConstructor = driverClass.getConstructor();            // make Constructor accessible if it is private            boolean isConstructorAccessible = driverConstructor.isAccessible();            if (!isConstructorAccessible) {                driverConstructor.setAccessible(true);            }            try {                Driver driver = driverConstructor.newInstance();                registerDriver(new DriverProxy(driver));            } finally {                driverConstructor.setAccessible(isConstructorAccessible);            }            return true;        } catch (RuntimeException e) {            return false;        } catch (Exception e) {            return false;        }    }

这个方法执行过程如下:
用指定的类加载器加载指定驱动类

Class<?> loadedClass = classLoader.loadClass(driverClassName);

判断loadedClass是否实现了java.sql.Driver接口

if (!Driver.class.isAssignableFrom(loadedClass)) {                return false;            }

如果是,获取loadedClass 的构造函数,并设置可以访问,

                driverConstructor.setAccessible(true);

获取驱动实例,注册驱动。

Driver driver = driverConstructor.newInstance();                registerDriver(new DriverProxy(driver));

查看Driver接口,可以看到getParentLogger方法是JDBC4.1新增的,

//------------------------- JDBC 4.1 -----------------------------------    /**     * Return the parent Logger of all the Loggers used by this driver. This     * should be the Logger farthest from the root Logger that is     * still an ancestor of all of the Loggers used by this driver. Configuring     * this Logger will affect all of the log messages generated by the driver.     * In the worst case, this may be the root Logger.     *     * @return the parent Logger for this driver     * @throws SQLFeatureNotSupportedException if the driver does not use     * {@code java.util.logging}.     * @since 1.7     */    public Logger getParentLogger() throws SQLFeatureNotSupportedException;

因此利用DriverProxy解决JDK7与JDK6 Driver接口之间的不兼容问题。

 /**         * Java 1.7 method.         */        public Logger getParentLogger() throws SQLFeatureNotSupportedException {            if (parentLoggerSupported) {                try {                    Method method = adapted.getClass().getMethod("getParentLogger", new Class[0]);                    return (Logger)method.invoke(adapted, new Object[0]);                } catch (NoSuchMethodException e) {                    parentLoggerSupported = false;                    throw new SQLFeatureNotSupportedException(e);                } catch (IllegalAccessException e) {                    parentLoggerSupported = false;                    throw new SQLFeatureNotSupportedException(e);                } catch (InvocationTargetException e) {                    parentLoggerSupported = false;                    throw new SQLFeatureNotSupportedException(e);                }            }            throw new SQLFeatureNotSupportedException();        }
0 0
原创粉丝点击