java --关于jdbc的一点思考--DriverManager如何知道用哪个驱动

要理解的其实要把握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判断,不要忘了参数的作用。

发布了78 篇原创文章 · 获赞 3 · 访问量 6600

猜你喜欢

转载自blog.csdn.net/weixin_38023259/article/details/104146525