DriverManager.getConnection的底层如何实现(非机器级别)
前言
DriverManager.getConnection的目标是获得一个Connection,而Connection的关键部分在于QueryExecutor
顺序
DriverManager的getConnection的实现方法,实际上是对其存储的每个"Driver"(实际并非直接存储Driver类型引用)尝试执行Driver.connect(url,info);
Driver.connect(url,info)方法,则是先将本地的配置信息、url中携带的配置信息组合到info(props)中,继而执行Driver.makeConnection(url,props)获得对应的Connection实现类型;
对于PG,Driver.makeConnection(url,props)调用PgConnection的构造方法:PgConnection(hostSpecs(props), props, url)。hostSpecs(props)从props(Properties对象)中解析出PostgreSQL数据库的主机名、端口号以及本地socket地址,并构建一一对应的数组。
而PgConnection(hostSpecs(props), props, url)的关键在于this.queryExecutor = ConnectionFactory.openConnection(hostSpecs, info),获得一个queryExecutor实例;
而ConnectionFactory.openConnectionImp(hostSpecs, info)的关键步骤在于:
- 根据info建立一个SocketFactory;
- 建立hostSpec--targetServerType对应关系数组,对每个数组进行遍历:
- 执行ConnectionFactory.tryConnect(info, socketFactory, hostSpec, sslMode, gssEncMode)获得一个new PgStream;
- 构建一个PGStream:PGStream(socketFactory, hostSpec, connectTimeout, maxSendBufferSize);
- PGStream(socketFactory, hostSpec, connectTimeout, maxSendBufferSize)关键在于新建一个socket,并建立该socket的输入输出流和缓冲区;
- createSocket(timeout):新建socket
- changeSocket(socket):建立该socket的输入输出流
- PGStream(socketFactory, hostSpec, connectTimeout, maxSendBufferSize)关键在于新建一个socket,并建立该socket的输入输出流和缓冲区;
- 构建一个PGStream:PGStream(socketFactory, hostSpec, connectTimeout, maxSendBufferSize);
- 使用QueryExecutorImpl(newStream, cancelSignalTimeout, info)构建所求的QueryExecutor;
- 执行ConnectionFactory.tryConnect(info, socketFactory, hostSpec, sslMode, gssEncMode)获得一个new PgStream;