0x00 前言
上一节分析了jdbc的Driver注册过程,这一节分析一下jdbc是如何获取connection的。
0x01 connection的建立过程
DriverManager.getConnection
做了什么
conn = DriverManager.getConnection("jdbc:mysql://192.168.108.145/test", "root", "root");
可以看出,getConnection
方法返回的是一个Connection对象,在下面的for循环中,会遍历registeredDrivers中存放的所有的Driver,直到找到一个合适的Driver,然后进行连接。通过这个方法我已经可以知道jdbc就是这样来获取连接的,但是具体是怎么来获取这个connection,还需要详细地看后面的代码。
private static Connection getConnection(
String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
......
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);
}
}
......
}
connect
方法
java.sql.Driver
接口中定义了一个connect方法,然后由具体的实现类来完成connect的功能。
我们先看一下mysql的实现。
在com.mysql.jdbc.Driver
中,并没有详细的实现,但是它继承了NonRegisteringDriver,那么connect应该就在NonRegisteringDriver中了。
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
}
}
现在定位到com.mysql.jdbc.NonRegisteringDriver
的connect
中。
可以看出,有一句if ((props = parseURL(url, info)) == null)
来对url进行判断,如果url不符合规则的话,就会返回一个null值,这里的url就是指我们在程序中写的jdbc:mysql://192.168.108.145/test
这样的语句。mysql的parseURL
方法十分十分的长,暂时不再细究它了…
继续向下看,可以发现具体的获取连接的地方在com.mysql.jdbc.ConnectionImpl.getInstance
。
public java.sql.Connection connect(String url, Properties info) throws SQLException {
if (url != null) {
if (StringUtils.startsWithIgnoreCase(url, LOADBALANCE_URL_PREFIX)) {
return connectLoadBalanced(url, info);
} else if (StringUtils.startsWithIgnoreCase(url, REPLICATION_URL_PREFIX)) {
return connectReplicationConnection(url, info);
}
}
Properties props = null;
if ((props = parseURL(url, info)) ==