JDBC 的 getConnection连接源码解析

2022-06-14  本文已影响0人  kacen

本篇对jdbc的获取连接进行解析
1.这里是直接上代码哈,它的getConnection会通过相对应调用的重载方法来进行不同的操作,我们主要看我们常规的连接方式。

 @CallerSensitive
    public static Connection getConnection(String url,
        String user, String password) throws SQLException {
        //存放相关配置属性
        java.util.Properties info = new java.util.Properties();
        if (user != null) {
            info.put("user", user);
        }
        if (password != null) {
            info.put("password", password);
        }
        //会继续调用本类getConnection方法,并传入反射的getCallerClass方法。
        return (getConnection(url, info, Reflection.getCallerClass()));
    }

继续之前需要解释一下@CallerSensitive
@CallerSensitive开发者正常调用是不起作用的,因为java并不希望我们调用该方法。(它也是可以被调用的, -Xbootclasspath/a: path 在jvm启动进行配置)它必须有启动类ClassLoader加载(比如rt.jar才能被识别)。
Reflection.getCallerClass()这个方法就必须加上@CallerSensitive配合使用。
它这里是做什么用的??
2.然后我们继续往下看(看注解哦)

//  Worker method called by the public getConnection() methods.
    private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException {
        /*
         * When callerCl is null, we should check the application's
         * (which is invoking this class indirectly)
         * classloader, so that the JDBC driver class outside rt.jar
         * can be loaded from here.
         */
        //这里的话就基本大概知道为什么了,它在这里的话就会通过它来获取的我们的数据库连接的驱动。
        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            // synchronize loading of the correct classloader.
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

        if(url == null) {
            throw new SQLException("The url cannot be null", "08001");
        }

        println("DriverManager.getConnection(\"" + url + "\")");

        // Walk through the loaded registeredDrivers attempting to make a connection.
        // Remember the first exception that gets raised so we can reraise it.
        SQLException reason = null;
        //这里的话就会获取完后并通过配置进行连接,最后返回Connection。
        for(DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }

            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }

        }
        //如果走到这里就是百分百有问题啦,就是报错的原因会在这抛出。
        // if we got here nobody could connect.
        if (reason != null)    {
            println("getConnection failed: " + reason);
            throw reason;
        }
        //走到这里的话就是找不到合适的驱动
        println("getConnection: no suitable driver found for "+ url);
        throw new SQLException("No suitable driver found for "+ url, "08001");
    }

上一篇下一篇

猜你喜欢

热点阅读