refactor DruidDataSource

This commit is contained in:
wenshao
2012-08-17 09:11:32 +08:00
parent dc7d7062b0
commit 0226c4cba4
4 changed files with 110 additions and 179 deletions
@@ -1,27 +0,0 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.pool;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @author wenshao<szujobs@hotmail.com>
*/
public interface ConnectionFactory {
Connection createConnection() throws SQLException;
}
@@ -46,6 +46,8 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.sql.DataSource;
import org.h2.util.StringUtils;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.FilterChainImpl;
import com.alibaba.druid.filter.FilterManager;
@@ -111,8 +113,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected volatile PasswordCallback passwordCallback;
protected volatile NameCallback userCallback;
protected ConnectionFactory connectionFactory;
protected volatile int initialSize = DEFAULT_INITIAL_SIZE;
protected volatile int maxActive = DEFAULT_MAX_ACTIVE_SIZE;
protected volatile int minIdle = DEFAULT_MIN_IDLE;
@@ -787,9 +787,9 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
if (maxWaitMillis == this.maxWait) {
return;
}
if (inited) {
LOG.error("maxWait modified : " + this.maxWait + " -> " + maxWaitMillis);
LOG.error("maxWait changed : " + this.maxWait + " -> " + maxWaitMillis);
}
this.maxWait = maxWaitMillis;
@@ -803,13 +803,14 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
if (value == this.minIdle) {
return;
}
if (inited) {
if (value > this.maxActive) {
throw new IllegalArgumentException("minIdle greater than maxActive, " + maxActive + " < " + this.minIdle);
throw new IllegalArgumentException("minIdle greater than maxActive, " + maxActive + " < "
+ this.minIdle);
}
LOG.error("minIdle modified : " + this.minIdle + " -> " + value);
LOG.error("minIdle changed : " + this.minIdle + " -> " + value);
}
this.minIdle = value;
@@ -819,10 +820,9 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
return maxIdle;
}
@Deprecated
public void setMaxIdle(int maxIdle) {
if (inited) {
throw new UnsupportedOperationException();
}
LOG.error("maxIdle is deprecated");
this.maxIdle = maxIdle;
}
@@ -832,6 +832,10 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public void setInitialSize(int initialSize) {
if (this.initialSize == initialSize) {
return;
}
if (inited) {
throw new UnsupportedOperationException();
}
@@ -866,8 +870,12 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public void setPassword(String password) {
if (StringUtils.equals(this.password, password)) {
return;
}
if (inited) {
throw new UnsupportedOperationException();
LOG.info("password changed");
}
this.password = password;
@@ -970,22 +978,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
return DriverManager.getLoginTimeout();
}
protected void initConnectionFactory() throws SQLException {
if (connectionFactory != null) {
return;
}
connectionFactory = createConnectionFactory();
}
public ConnectionFactory getConnectionFactory() {
return connectionFactory;
}
protected ConnectionFactory createConnectionFactory() throws SQLException {
return new DruidPoolConnectionFactory(this);
}
public Driver getDriver() {
return driver;
}
@@ -1235,125 +1227,106 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
return new FilterChainImpl(this).connection_connect(info);
}
public static class DruidPoolConnectionFactory implements ConnectionFactory {
public Connection createConnection() throws SQLException {
String url = this.getUrl();
Properties info;
private final String url;
private final Properties info;
private final DruidAbstractDataSource dataSource;
Properties properties = getConnectProperties();
String user;
if (getUserCallback() != null) {
user = getUserCallback().getName();
} else {
user = getUsername();
}
public DruidPoolConnectionFactory(DruidAbstractDataSource dataSource) throws SQLException{
this.dataSource = dataSource;
this.url = dataSource.getUrl();
String password = getPassword();
PasswordCallback passwordCallback = getPasswordCallback();
Properties properties = dataSource.getConnectProperties();
String user;
if (dataSource.getUserCallback() != null) {
user = dataSource.getUserCallback().getName();
} else {
user = dataSource.getUsername();
}
if (passwordCallback instanceof DruidPasswordCallback) {
DruidPasswordCallback druidPasswordCallback = (DruidPasswordCallback) passwordCallback;
String password = dataSource.getPassword();
PasswordCallback passwordCallback = dataSource.getPasswordCallback();
druidPasswordCallback.setUrl(url);
druidPasswordCallback.setProperties(properties);
}
if (passwordCallback instanceof DruidPasswordCallback) {
DruidPasswordCallback druidPasswordCallback = (DruidPasswordCallback) passwordCallback;
info = new Properties(getConnectProperties());
druidPasswordCallback.setUrl(url);
druidPasswordCallback.setProperties(properties);
}
if (properties != null) {
info.putAll(properties);
}
this.info = new Properties(dataSource.getConnectProperties());
if ((!info.contains("user")) && user != null) {
info.put("user", user);
}
if (properties != null) {
info.putAll(properties);
}
if ((!info.contains("password")) && password != null) {
info.put("password", password);
}
if ((!info.contains("user")) && user != null) {
info.put("user", user);
}
Connection conn;
if ((!info.contains("password")) && password != null) {
info.put("password", password);
if (passwordCallback != null) {
char[] chars = passwordCallback.getPassword();
if (chars != null) {
String callbackPassword = new String(chars);
info.put("password", callbackPassword);
}
}
public String getUrl() {
return url;
long startNano = System.nanoTime();
try {
conn = createPhysicalConnection(url, info);
if (conn == null) {
throw new SQLException("connect error, url " + url);
}
initPhysicalConnection(conn);
validateConnection(conn);
createError = null;
} catch (SQLException ex) {
createErrorCount++;
createError = ex;
lastCreateError = ex;
lastCreateErrorTimeMillis = System.currentTimeMillis();
throw ex;
} catch (RuntimeException ex) {
createErrorCount++;
createError = ex;
lastCreateError = ex;
lastCreateErrorTimeMillis = System.currentTimeMillis();
throw ex;
} catch (Error ex) {
createErrorCount++;
throw ex;
} finally {
long nano = System.nanoTime() - startNano;
createTimespan += nano;
}
public Properties getInfo() {
return info;
incrementCreateCount();
return conn;
}
public void initPhysicalConnection(Connection conn) throws SQLException {
conn.setAutoCommit(isDefaultAutoCommit());
if (getDefaultReadOnly() != null) {
if (conn.isReadOnly() != getDefaultReadOnly()) {
conn.setReadOnly(getDefaultReadOnly());
}
}
@Override
public Connection createConnection() throws SQLException {
Connection conn;
PasswordCallback passwordCallback = dataSource.getPasswordCallback();
if (passwordCallback != null) {
char[] chars = passwordCallback.getPassword();
if (chars != null) {
String callbackPassword = new String(chars);
info.put("password", callbackPassword);
}
if (getDefaultTransactionIsolation() != null) {
if (conn.getTransactionIsolation() != getDefaultTransactionIsolation().intValue()) {
conn.setTransactionIsolation(getDefaultTransactionIsolation());
}
long startNano = System.nanoTime();
try {
conn = dataSource.createPhysicalConnection(url, info);
if (conn == null) {
throw new SQLException("connect error, url " + url);
}
initConnection(conn);
dataSource.validateConnection(conn);
dataSource.createError = null;
} catch (SQLException ex) {
dataSource.createErrorCount++;
dataSource.createError = ex;
dataSource.lastCreateError = ex;
dataSource.lastCreateErrorTimeMillis = System.currentTimeMillis();
throw ex;
} catch (RuntimeException ex) {
dataSource.createErrorCount++;
dataSource.createError = ex;
dataSource.lastCreateError = ex;
dataSource.lastCreateErrorTimeMillis = System.currentTimeMillis();
throw ex;
} catch (Error ex) {
dataSource.createErrorCount++;
throw ex;
} finally {
long nano = System.nanoTime() - startNano;
dataSource.createTimespan += nano;
}
dataSource.incrementCreateCount();
return conn;
}
public void initConnection(Connection conn) throws SQLException {
conn.setAutoCommit(dataSource.isDefaultAutoCommit());
if (dataSource.getDefaultReadOnly() != null) {
if (conn.isReadOnly() != dataSource.getDefaultReadOnly()) {
conn.setReadOnly(dataSource.getDefaultReadOnly());
}
}
if (dataSource.getDefaultTransactionIsolation() != null) {
if (conn.getTransactionIsolation() != dataSource.getDefaultTransactionIsolation().intValue()) {
conn.setTransactionIsolation(dataSource.getDefaultTransactionIsolation());
}
}
if (dataSource.getDefaultCatalog() != null && dataSource.getDefaultCatalog().length() != 0) {
conn.setCatalog(dataSource.getDefaultCatalog());
}
if (getDefaultCatalog() != null && getDefaultCatalog().length() != 0) {
conn.setCatalog(getDefaultCatalog());
}
}
@@ -1584,7 +1557,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
to.connectionProperties = this.connectionProperties;
to.passwordCallback = this.passwordCallback;
to.userCallback = this.userCallback;
to.connectionFactory = this.connectionFactory;
to.initialSize = this.initialSize;
to.maxActive = this.maxActive;
to.minIdle = this.minIdle;
@@ -267,7 +267,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
if (LOG.isInfoEnabled()) {
LOG.info("maxActive modified : " + this.maxActive + " -> " + maxActive);
LOG.info("maxActive changed : " + this.maxActive + " -> " + maxActive);
}
lock.lock();
@@ -378,8 +378,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
initConnectionFactory();
connections = new ConnectionHolder[maxActive];
SQLException connectError = null;
@@ -387,7 +385,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
try {
// 初始化连接
for (int i = 0, size = getInitialSize(); i < size; ++i) {
Connection conn = connectionFactory.createConnection();
Connection conn = createConnection();
if (defaultAutoCommit != conn.getAutoCommit()) {
conn.setAutoCommit(defaultAutoCommit);
}
@@ -1125,7 +1123,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
Connection connection = null;
try {
connection = connectionFactory.createConnection();
connection = createConnection();
} catch (SQLException e) {
LOG.error("create connection error", e);
@@ -93,20 +93,13 @@ public class DataSourceTest3 extends TestCase {
dataSource.setMinIdle(1);
}
@SuppressWarnings("deprecation")
public void test_error_4() throws Exception {
DruidPooledConnection conn = dataSource.getConnection().unwrap(DruidPooledConnection.class);
conn.close();
{
Exception error = null;
try {
dataSource.setMaxIdle(1);
} catch (Exception ex) {
error = ex;
}
Assert.assertNotNull(error);
}
dataSource.setMaxIdle(1);
}
public void test_error_5() throws Exception {
@@ -114,10 +107,12 @@ public class DataSourceTest3 extends TestCase {
conn.close();
dataSource.setInitialSize(dataSource.getInitialSize());
{
Exception error = null;
try {
dataSource.setInitialSize(1);
dataSource.setInitialSize(10);
} catch (Exception ex) {
error = ex;
}
@@ -138,15 +133,8 @@ public class DataSourceTest3 extends TestCase {
conn.close();
{
Exception error = null;
try {
dataSource.setPassword("xx");
} catch (Exception ex) {
error = ex;
}
Assert.assertNotNull(error);
}
dataSource.setPassword(dataSource.getPassword());
dataSource.setPassword("xx");
}
public void test_error_8() throws Exception {