DbUtils源码分析系列(三)

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

DbUtils源码分析系列(三)_第1张图片
从类图中很容易看出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 true if the driver was found, otherwise false
     */
    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 true if the driver was found, otherwise false
     * @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 driverClass = (Class) loadedClass;
            Constructor 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();
        }

你可能感兴趣的:(DButils)