要理解的其实要把握Connection一直是一个接口,对象引用的实现类才是厂商实现的,DriverManager的调用是具体怎么样的?怎么知道用的是哪个驱动?查了一些博文,终于有点眉目了。
以下皆为转载:
======================================================
来自 https://bbs.csdn.net/topics/392006642
DriverManager.getConnection()是怎么确定用哪个DriverClass?
假设我调用了一次Class.forName(MySqlDriver),然后又调用了一次Class.forName(OracleDriver),这样就向DriverManager中注册了两个驱动。这时候再调用getConnection(),会用哪个driver?
我大概看了一下getConnection的源码,getConnection()方法会迭代DriverManager中注册的所有的DriverInfo,通过isDriverAllowed接口判断当前driver是否被使用,(见图)。
isDriverAllowed中又调用了Class.forName()根据当前driver的Name和classloader加载一个Driver与当前Driver比较。但是Class.forName()里的逻辑就看不懂了,(如图)
求大神指教。
关于isDriverAllowed,我在想,因为我调用两次Class.forName(DriverName)时,都是在一个方法中,那么遍历这些Driver所获取的classloader不都是一样的吗?然后根据name和classloader获取的driver肯定也和当前的相等啊,这样isDriverAllowed还有什么意义?
难道我调用Class.forName(OracleDriver)会把之前注册的MySqlDriver覆盖掉?但是我看了DriverManager.registerDriver()的逻辑,在注册的时候只会判断之前的集合中有没有同一个driver类啊,如果没有就会添加。也就是说MySqlDriver和OracleDriver都会被添加才对。。。
还有,classLoader是根据Reflection.getCallerClass()获取的,这个接口的作用不是太懂。。。
还真没考虑过这个问题,不过我相信你的理解是对的。否则多线程下不同数据库的连接不乱套了。
其实要验证下也容易。比如下面的伪代码。
Class.forName(MySqlDriver);
Class.forName(OracleDriver);
connection con1 = DriverManager.getConnection(mysqlURL, userName, password);
connection con2 = DriverManager.getConnection(oracleURL, userName, password);
如果con1和con2都可以正常获取,不就验证了你的想法是正确的吗。
我没环境,楼主请自行验证。
转载结束
====================================================
很简单讲就是会根据url判断,不要忘了参数的作用。