1.UNPOOLED
下面UnpooledDataSource getConnection源码
public Connection getConnection() throws SQLException {
return this.doGetConnection(this.username, this.password);
}
private Connection doGetConnection(String username, String password) throws SQLException {
Properties props = new Properties();
if (this.driverProperties != null) {
props.putAll(this.driverProperties);
}
if (username != null) {
props.setProperty("user", username);
}
if (password != null) {
props.setProperty("password", password);
}
return this.doGetConnection(props);
}
在这个方法中先创建了一个Properties对象,这个对象是用来专门配置属性的对象,在这之后添加了配置数据库连接的username和password属性,并调用了doGetConnection方法,并传入了props对象;
private Connection doGetConnection(Properties properties) throws SQLException {
this.initializeDriver();
Connection connection = DriverManager.getConnection(this.url, properties);
this.configureConnection(connection);
return connection;
}
这个方法就比较清楚,首先大概能猜到第一行initializeDriver()在注册驱动
private synchronized void initializeDriver() throws SQLException {
if (!registeredDrivers.containsKey(this.driver)) {
try {
Class driverType;
if (this.driverClassLoader != null) {
driverType = Class.forName(this.driver, true, this.driverClassLoader);
} else {
driverType = Resources.classForName(this.driver);
}
Driver driverInstance = (Driver)driverType.newInstance();
DriverManager.registerDriver(new UnpooledDataSource.DriverProxy(driverInstance));
registeredDrivers.put(this.driver, driverInstance);
} catch (Exception var3) {
throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + var3);
}
}
}
确实,这个方法实在注册驱动
第二行就是获取connection了,后面就直接返回了。
2.POOLED
在getConnection中调用了popConnection
public Connection getConnection() throws SQLException {
return this.popConnection(this.dataSource.getUsername(), this.dataSource.getPassword()).getProxyConnection();
}
下面来分析一下popConnection方法的源码
首先,获取连接必须保证线程安全,所以带上synchronized代码块
synchronized(this.state) {
下一句,判断是否在线程池中是否由空闲连接
if (!this.state.idleConnections.isEmpty()) {
如果有,就直接从线程池中获取第一个
conn = (PooledConnection)this.state.idleConnections.remove(0);
这里的idleConnections就是一个放置连接的集合
protected final List<PooledConnection> idleConnections = new ArrayList();
如果没有,判断另外一个已使用池中的最大连接数量是否大于当前的使用连接数量
else if (this.state.activeConnections.size() < this.poolMaximumActiveConnections)
如果大于,就在创建一个连接进行返回
conn = new PooledConnection(this.dataSource.getConnection(), this);
如果空闲池为空,使用池的连接数也已达到最大使用连接数,就从使用池中取出一个最久的连接,也就是最早的连接,清空属性保证它是一个纯净的连接后返回
PooledConnection oldestActiveConnection = (PooledConnection)this.state.activeConnections.get(0);
long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
if (longestCheckoutTime > (long)this.poolMaximumCheckoutTime) {
++this.state.claimedOverdueConnectionCount;
var10000 = this.state;
var10000.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
var10000 = this.state;
var10000.accumulatedCheckoutTime += longestCheckoutTime;
this.state.activeConnections.remove(oldestActiveConnection);
if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
try {
oldestActiveConnection.getRealConnection().rollback();
} catch (SQLException var16) {
log.debug("Bad connection. Could not roll back");
}
}
conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());
conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());
oldestActiveConnection.invalidate();
if (log.isDebugEnabled()) {
log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
}
} else {
try {
if (!countedWait) {
++this.state.hadToWaitCount;
countedWait = true;
}
if (log.isDebugEnabled()) {
log.debug("Waiting as long as " + this.poolTimeToWait + " milliseconds for connection.");
}
long wt = System.currentTimeMillis();
this.state.wait((long)this.poolTimeToWait);
var10000 = this.state;
var10000.accumulatedWaitTime += System.currentTimeMillis() - wt;
} catch (InterruptedException var17) {
break;
}
总结
POOLED采用的是连接池的方式,而UNPOOLED则采用是单独获取一个连接的方式