Mybatis自带的数据库连接池PooledDataSource 源码解析
1.PooledConnection 类
该类是一个 连接代理类 实现了 InvocationHandler接口。
class PooledConnection implements InvocationHandler {
private PooledDataSource dataSource; //数据源
private Connection realConnection; //连接对象
private Connection proxyConnection; //该连接对象的代理对象
//构造方法 初始化该连接对象的时候同时生成该连接对象的代理对象
public PooledConnection(Connection connection, PooledDataSource dataSource) {
this.hashCode = connection.hashCode();
this.realConnection = connection;
this.dataSource = dataSource;
this.createdTimestamp = System.currentTimeMillis();
this.lastUsedTimestamp = System.currentTimeMillis();
this.valid = true;
//生成代理对象
this.proxyConnection = (Connection)Proxy.newProxyInstance(Connection.class.getClassLoader(), IFACES, this);
}
// 核心方法 重写 inoke 方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
//核心思想 如果该连接调用了close 方法,把该连接返还给连接池中
if ("close".hashCode() == methodName.hashCode() && "close".equals(methodName)) {
this.dataSource.pushConnection(this);
return null;
} else {
try {
if (!Object.class.equals(method.getDeclaringClass())) {
this.checkConnection();
}
// 利用反射 使用真是的connection对象 进行方法的调用
return method.invoke(this.realConnection, args);
} catch (Throwable var6) {
throw ExceptionUtil.unwrapThrowable(var6);
}
}
}
}
2.UnpooledDataSource类
非数据库连接池类,该类维护了连接数据库的基本信息,driver、url、username、password…
public class UnpooledDataSource implements DataSource {
private ClassLoader driverClassLoader;
private Properties driverProperties;
private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap();
private String driver;
private String url;
private String username;
private String password;
...
}
3.PooledDataSource类
该类是数据库连接池的核心类,实现了DataSource接口
public class PooledDataSource implements DataSource {
private final PoolState state = new PoolState(this); //该类是维护连接的类
private final UnpooledDataSource dataSource;//连接数据库的基本信息 都在该类里面
protected int poolMaximumActiveConnections = 10;//在任意时间存在的活动连接的数量
protected int poolMaximumIdleConnections = 5;//任意时间存在的空闲连接数。
protected int poolMaximumCheckoutTime = 20000;
protected int poolTimeToWait = 20000;
...
//该类的构造函数 返回一个UnPooledDataSource
public PooledDataSource(String driver, String url, String username, String password) {
this.dataSource = new UnpooledDataSource(driver, url, username, password);
...
}
//获取连接的方法 返回的是一个代理连接
public Connection getConnection() throws SQLException {
return this.popConnection(this.dataSource.getUsername(), this.dataSource.getPassword()).getProxyConnection();
}
// popConnection 方法
private PooledConnection popConnection(String username, String password) throws SQLException {
...
//核心点 该方法里面会生成一个PooledConnection 对象,该对象上面已经分析过了,会生成一个代理连接
conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
...
}
-
PoolState类
该类里面维护了与数据库的连接。
public class PoolState { protected PooledDataSource dataSource; protected final List<PooledConnection> idleConnections = new ArrayList(); protected final List<PooledConnection> activeConnections = new ArrayList(); }
核心思想:PooledDataSource在获取连接的时候,返回的是一个代理对象,该对象调用close方法的时候,不会真正的释放与数据库的连接,而是把该连接返还给连接池。