一、前言
关于apache的dbcp的数据库连接池实现工厂类org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory(具体配置用法说明参考其它文章)基于javax.naming.spi.ObjectFactory对象工厂定义接口,对实现了javax.sql.DataSource的数据源接口org.apache.tomcat.dbcp.dbcp.BasicDataSource工厂化管理对象的资源,详情参见如下源码说明部分。
二、源码说明
1.BasicDataSource类(属性具体说明参见其他页)
package org.apache.tomcat.dbcp.dbcp;@b@@b@import java.io.PrintWriter;@b@import java.sql.Connection;@b@import java.sql.Driver;@b@import java.sql.DriverManager;@b@import java.sql.SQLException;@b@import java.util.ArrayList;@b@import java.util.Collection;@b@import java.util.Collections;@b@import java.util.Iterator;@b@import java.util.List;@b@import java.util.Properties;@b@import javax.sql.DataSource;@b@import org.apache.tomcat.dbcp.pool.KeyedObjectPoolFactory;@b@import org.apache.tomcat.dbcp.pool.impl.GenericKeyedObjectPoolFactory;@b@import org.apache.tomcat.dbcp.pool.impl.GenericObjectPool;@b@@b@public class BasicDataSource@b@ implements DataSource@b@{@b@ protected volatile boolean defaultAutoCommit;@b@ protected transient Boolean defaultReadOnly;@b@ protected volatile int defaultTransactionIsolation;@b@ protected volatile String defaultCatalog;@b@ protected String driverClassName;@b@ protected ClassLoader driverClassLoader;@b@ protected int maxActive;@b@ protected int maxIdle;@b@ protected int minIdle;@b@ protected int initialSize;@b@ protected long maxWait;@b@ protected boolean poolPreparedStatements;@b@ protected int maxOpenPreparedStatements;@b@ protected boolean testOnBorrow;@b@ protected boolean testOnReturn;@b@ protected long timeBetweenEvictionRunsMillis;@b@ protected int numTestsPerEvictionRun;@b@ protected long minEvictableIdleTimeMillis;@b@ protected boolean testWhileIdle;@b@ protected volatile String password;@b@ protected String url;@b@ protected String username;@b@ protected volatile String validationQuery;@b@ protected volatile int validationQueryTimeout;@b@ protected volatile List connectionInitSqls;@b@ private boolean accessToUnderlyingConnectionAllowed;@b@ private volatile boolean restartNeeded;@b@ protected volatile GenericObjectPool connectionPool;@b@ protected Properties connectionProperties;@b@ protected volatile DataSource dataSource;@b@ protected PrintWriter logWriter;@b@ private AbandonedConfig abandonedConfig;@b@ protected boolean closed;@b@@b@ public BasicDataSource()@b@ {@b@ this.defaultAutoCommit = true;@b@@b@ this.defaultReadOnly = null;@b@@b@ this.defaultTransactionIsolation = -1;@b@@b@ this.defaultCatalog = null;@b@@b@ this.driverClassName = null;@b@@b@ this.driverClassLoader = null;@b@@b@ this.maxActive = 8;@b@@b@ this.maxIdle = 8;@b@@b@ this.minIdle = 0;@b@@b@ this.initialSize = 0;@b@@b@ this.maxWait = -1L;@b@@b@ this.poolPreparedStatements = false;@b@@b@ this.maxOpenPreparedStatements = -1;@b@@b@ this.testOnBorrow = true;@b@@b@ this.testOnReturn = false;@b@@b@ this.timeBetweenEvictionRunsMillis = -1L;@b@@b@ this.numTestsPerEvictionRun = 3;@b@@b@ this.minEvictableIdleTimeMillis = 1800000L;@b@@b@ this.testWhileIdle = false;@b@@b@ this.password = null;@b@@b@ this.url = null;@b@@b@ this.username = null;@b@@b@ this.validationQuery = null;@b@@b@ this.validationQueryTimeout = -1;@b@@b@ this.accessToUnderlyingConnectionAllowed = false;@b@@b@ this.restartNeeded = false;@b@@b@ this.connectionPool = null;@b@@b@ this.connectionProperties = new Properties();@b@@b@ this.dataSource = null;@b@@b@ this.logWriter = new PrintWriter(System.out);@b@ }@b@@b@ public boolean getDefaultAutoCommit()@b@ {@b@ return this.defaultAutoCommit;@b@ }@b@@b@ public void setDefaultAutoCommit(boolean defaultAutoCommit)@b@ {@b@ this.defaultAutoCommit = defaultAutoCommit;@b@ this.restartNeeded = true;@b@ }@b@@b@ public boolean getDefaultReadOnly()@b@ {@b@ Boolean val = this.defaultReadOnly;@b@ if (val != null)@b@ return val.booleanValue();@b@@b@ return false;@b@ }@b@@b@ public void setDefaultReadOnly(boolean defaultReadOnly)@b@ {@b@ this.defaultReadOnly = ((defaultReadOnly) ? Boolean.TRUE : Boolean.FALSE);@b@ this.restartNeeded = true;@b@ }@b@@b@ public int getDefaultTransactionIsolation()@b@ {@b@ return this.defaultTransactionIsolation;@b@ }@b@@b@ public void setDefaultTransactionIsolation(int defaultTransactionIsolation)@b@ {@b@ this.defaultTransactionIsolation = defaultTransactionIsolation;@b@ this.restartNeeded = true;@b@ }@b@@b@ public String getDefaultCatalog()@b@ {@b@ return this.defaultCatalog;@b@ }@b@@b@ public void setDefaultCatalog(String defaultCatalog)@b@ {@b@ if ((defaultCatalog != null) && (defaultCatalog.trim().length() > 0)) {@b@ this.defaultCatalog = defaultCatalog;@b@ }@b@ else@b@ this.defaultCatalog = null;@b@@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized String getDriverClassName()@b@ {@b@ return this.driverClassName;@b@ }@b@@b@ public synchronized void setDriverClassName(String driverClassName)@b@ {@b@ if ((driverClassName != null) && (driverClassName.trim().length() > 0)) {@b@ this.driverClassName = driverClassName;@b@ }@b@ else@b@ this.driverClassName = null;@b@@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized ClassLoader getDriverClassLoader()@b@ {@b@ return this.driverClassLoader;@b@ }@b@@b@ public synchronized void setDriverClassLoader(ClassLoader driverClassLoader)@b@ {@b@ this.driverClassLoader = driverClassLoader;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized int getMaxActive()@b@ {@b@ return this.maxActive;@b@ }@b@@b@ public synchronized void setMaxActive(int maxActive)@b@ {@b@ this.maxActive = maxActive;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setMaxActive(maxActive);@b@ }@b@@b@ public synchronized int getMaxIdle()@b@ {@b@ return this.maxIdle;@b@ }@b@@b@ public synchronized void setMaxIdle(int maxIdle)@b@ {@b@ this.maxIdle = maxIdle;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setMaxIdle(maxIdle);@b@ }@b@@b@ public synchronized int getMinIdle()@b@ {@b@ return this.minIdle;@b@ }@b@@b@ public synchronized void setMinIdle(int minIdle)@b@ {@b@ this.minIdle = minIdle;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setMinIdle(minIdle);@b@ }@b@@b@ public synchronized int getInitialSize()@b@ {@b@ return this.initialSize;@b@ }@b@@b@ public synchronized void setInitialSize(int initialSize)@b@ {@b@ this.initialSize = initialSize;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized long getMaxWait()@b@ {@b@ return this.maxWait;@b@ }@b@@b@ public synchronized void setMaxWait(long maxWait)@b@ {@b@ this.maxWait = maxWait;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setMaxWait(maxWait);@b@ }@b@@b@ public synchronized boolean isPoolPreparedStatements()@b@ {@b@ return this.poolPreparedStatements;@b@ }@b@@b@ public synchronized void setPoolPreparedStatements(boolean poolingStatements)@b@ {@b@ this.poolPreparedStatements = poolingStatements;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized int getMaxOpenPreparedStatements()@b@ {@b@ return this.maxOpenPreparedStatements;@b@ }@b@@b@ public synchronized void setMaxOpenPreparedStatements(int maxOpenStatements)@b@ {@b@ this.maxOpenPreparedStatements = maxOpenStatements;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized boolean getTestOnBorrow()@b@ {@b@ return this.testOnBorrow;@b@ }@b@@b@ public synchronized void setTestOnBorrow(boolean testOnBorrow)@b@ {@b@ this.testOnBorrow = testOnBorrow;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setTestOnBorrow(testOnBorrow);@b@ }@b@@b@ public synchronized boolean getTestOnReturn()@b@ {@b@ return this.testOnReturn;@b@ }@b@@b@ public synchronized void setTestOnReturn(boolean testOnReturn)@b@ {@b@ this.testOnReturn = testOnReturn;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setTestOnReturn(testOnReturn);@b@ }@b@@b@ public synchronized long getTimeBetweenEvictionRunsMillis()@b@ {@b@ return this.timeBetweenEvictionRunsMillis;@b@ }@b@@b@ public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis)@b@ {@b@ this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);@b@ }@b@@b@ public synchronized int getNumTestsPerEvictionRun()@b@ {@b@ return this.numTestsPerEvictionRun;@b@ }@b@@b@ public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun)@b@ {@b@ this.numTestsPerEvictionRun = numTestsPerEvictionRun;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);@b@ }@b@@b@ public synchronized long getMinEvictableIdleTimeMillis()@b@ {@b@ return this.minEvictableIdleTimeMillis;@b@ }@b@@b@ public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis)@b@ {@b@ this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);@b@ }@b@@b@ public synchronized boolean getTestWhileIdle()@b@ {@b@ return this.testWhileIdle;@b@ }@b@@b@ public synchronized void setTestWhileIdle(boolean testWhileIdle)@b@ {@b@ this.testWhileIdle = testWhileIdle;@b@ if (this.connectionPool != null)@b@ this.connectionPool.setTestWhileIdle(testWhileIdle);@b@ }@b@@b@ public synchronized int getNumActive()@b@ {@b@ if (this.connectionPool != null)@b@ return this.connectionPool.getNumActive();@b@@b@ return 0;@b@ }@b@@b@ public synchronized int getNumIdle()@b@ {@b@ if (this.connectionPool != null)@b@ return this.connectionPool.getNumIdle();@b@@b@ return 0;@b@ }@b@@b@ public String getPassword()@b@ {@b@ return this.password;@b@ }@b@@b@ public void setPassword(String password)@b@ {@b@ this.password = password;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized String getUrl()@b@ {@b@ return this.url;@b@ }@b@@b@ public synchronized void setUrl(String url)@b@ {@b@ this.url = url;@b@ this.restartNeeded = true;@b@ }@b@@b@ public String getUsername()@b@ {@b@ return this.username;@b@ }@b@@b@ public void setUsername(String username)@b@ {@b@ this.username = username;@b@ this.restartNeeded = true;@b@ }@b@@b@ public String getValidationQuery()@b@ {@b@ return this.validationQuery;@b@ }@b@@b@ public void setValidationQuery(String validationQuery)@b@ {@b@ if ((validationQuery != null) && (validationQuery.trim().length() > 0))@b@ this.validationQuery = validationQuery;@b@ else@b@ this.validationQuery = null;@b@@b@ this.restartNeeded = true;@b@ }@b@@b@ public int getValidationQueryTimeout()@b@ {@b@ return this.validationQueryTimeout;@b@ }@b@@b@ public void setValidationQueryTimeout(int timeout)@b@ {@b@ this.validationQueryTimeout = timeout;@b@ this.restartNeeded = true;@b@ }@b@@b@ public Collection getConnectionInitSqls()@b@ {@b@ Collection result = this.connectionInitSqls;@b@ if (result == null)@b@ return Collections.EMPTY_LIST;@b@@b@ return result;@b@ }@b@@b@ public void setConnectionInitSqls(Collection connectionInitSqls)@b@ {@b@ if ((connectionInitSqls != null) && (connectionInitSqls.size() > 0)) {@b@ ArrayList newVal = null;@b@ Iterator iterator = connectionInitSqls.iterator();@b@ while (iterator.hasNext()) {@b@ Object o = iterator.next();@b@ if (o != null) {@b@ String s = o.toString();@b@ if (s.trim().length() > 0) {@b@ if (newVal == null)@b@ newVal = new ArrayList();@b@@b@ newVal.add(s);@b@ }@b@ }@b@ }@b@ this.connectionInitSqls = newVal;@b@ } else {@b@ this.connectionInitSqls = null;@b@ }@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized boolean isAccessToUnderlyingConnectionAllowed()@b@ {@b@ return this.accessToUnderlyingConnectionAllowed;@b@ }@b@@b@ public synchronized void setAccessToUnderlyingConnectionAllowed(boolean allow)@b@ {@b@ this.accessToUnderlyingConnectionAllowed = allow;@b@ this.restartNeeded = true;@b@ }@b@@b@ private boolean isRestartNeeded()@b@ {@b@ return this.restartNeeded;@b@ }@b@@b@ public Connection getConnection()@b@ throws SQLException@b@ {@b@ return createDataSource().getConnection();@b@ }@b@@b@ public Connection getConnection(String user, String pass)@b@ throws SQLException@b@ {@b@ throw new UnsupportedOperationException("Not supported by BasicDataSource");@b@ }@b@@b@ public int getLoginTimeout()@b@ throws SQLException@b@ {@b@ throw new UnsupportedOperationException("Not supported by BasicDataSource");@b@ }@b@@b@ public PrintWriter getLogWriter()@b@ throws SQLException@b@ {@b@ return createDataSource().getLogWriter();@b@ }@b@@b@ public void setLoginTimeout(int loginTimeout)@b@ throws SQLException@b@ {@b@ throw new UnsupportedOperationException("Not supported by BasicDataSource");@b@ }@b@@b@ public void setLogWriter(PrintWriter logWriter)@b@ throws SQLException@b@ {@b@ createDataSource().setLogWriter(logWriter);@b@ this.logWriter = logWriter;@b@ }@b@@b@ public boolean getRemoveAbandoned()@b@ {@b@ if (this.abandonedConfig != null)@b@ return this.abandonedConfig.getRemoveAbandoned();@b@@b@ return false;@b@ }@b@@b@ public void setRemoveAbandoned(boolean removeAbandoned)@b@ {@b@ if (this.abandonedConfig == null)@b@ this.abandonedConfig = new AbandonedConfig();@b@@b@ this.abandonedConfig.setRemoveAbandoned(removeAbandoned);@b@ this.restartNeeded = true;@b@ }@b@@b@ public int getRemoveAbandonedTimeout()@b@ {@b@ if (this.abandonedConfig != null)@b@ return this.abandonedConfig.getRemoveAbandonedTimeout();@b@@b@ return 300;@b@ }@b@@b@ public void setRemoveAbandonedTimeout(int removeAbandonedTimeout)@b@ {@b@ if (this.abandonedConfig == null)@b@ this.abandonedConfig = new AbandonedConfig();@b@@b@ this.abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout);@b@ this.restartNeeded = true;@b@ }@b@@b@ public boolean getLogAbandoned()@b@ {@b@ if (this.abandonedConfig != null)@b@ return this.abandonedConfig.getLogAbandoned();@b@@b@ return false;@b@ }@b@@b@ public void setLogAbandoned(boolean logAbandoned)@b@ {@b@ if (this.abandonedConfig == null)@b@ this.abandonedConfig = new AbandonedConfig();@b@@b@ this.abandonedConfig.setLogAbandoned(logAbandoned);@b@ this.restartNeeded = true;@b@ }@b@@b@ public void addConnectionProperty(String name, String value)@b@ {@b@ this.connectionProperties.put(name, value);@b@ this.restartNeeded = true;@b@ }@b@@b@ public void removeConnectionProperty(String name)@b@ {@b@ this.connectionProperties.remove(name);@b@ this.restartNeeded = true;@b@ }@b@@b@ public void setConnectionProperties(String connectionProperties)@b@ {@b@ if (connectionProperties == null) throw new NullPointerException("connectionProperties is null");@b@@b@ String[] entries = connectionProperties.split(";");@b@ Properties properties = new Properties();@b@ for (int i = 0; i < entries.length; ++i) {@b@ String entry = entries[i];@b@ if (entry.length() > 0) {@b@ int index = entry.indexOf(61);@b@ if (index > 0) {@b@ String name = entry.substring(0, index);@b@ String value = entry.substring(index + 1);@b@ properties.setProperty(name, value);@b@ }@b@ else {@b@ properties.setProperty(entry, "");@b@ }@b@ }@b@ }@b@ this.connectionProperties = properties;@b@ this.restartNeeded = true;@b@ }@b@@b@ public synchronized void close()@b@ throws SQLException@b@ {@b@ this.closed = true;@b@ GenericObjectPool oldpool = this.connectionPool;@b@ this.connectionPool = null;@b@ this.dataSource = null;@b@ try {@b@ if (oldpool != null)@b@ oldpool.close();@b@ }@b@ catch (SQLException e) {@b@ throw e;@b@ } catch (RuntimeException e) {@b@ throw e;@b@ } catch (Exception e) {@b@ throw new SQLNestedException("Cannot close connection pool", e);@b@ }@b@ }@b@@b@ public synchronized boolean isClosed()@b@ {@b@ return this.closed;@b@ }@b@@b@ protected synchronized DataSource createDataSource()@b@ throws SQLException@b@ {@b@ int i;@b@ if (this.closed) {@b@ throw new SQLException("Data source is closed");@b@ }@b@@b@ if (this.dataSource != null) {@b@ return this.dataSource;@b@ }@b@@b@ ConnectionFactory driverConnectionFactory = createConnectionFactory();@b@@b@ createConnectionPool();@b@@b@ GenericKeyedObjectPoolFactory statementPoolFactory = null;@b@ if (isPoolPreparedStatements()) {@b@ statementPoolFactory = new GenericKeyedObjectPoolFactory(null, -1, 0, 0L, 1, this.maxOpenPreparedStatements);@b@ }@b@@b@ createPoolableConnectionFactory(driverConnectionFactory, statementPoolFactory, this.abandonedConfig);@b@@b@ createDataSourceInstance();@b@ try@b@ {@b@ for (i = 0; i < this.initialSize; ++i)@b@ this.connectionPool.addObject();@b@ }@b@ catch (Exception e) {@b@ throw new SQLNestedException("Error preloading the connection pool", e);@b@ }@b@@b@ return this.dataSource;@b@ }@b@@b@ protected ConnectionFactory createConnectionFactory()@b@ throws SQLException@b@ {@b@ Class driverFromCCL = null;@b@ if (this.driverClassName != null) {@b@ try {@b@ try {@b@ if (this.driverClassLoader == null)@b@ Class.forName(this.driverClassName);@b@ else@b@ Class.forName(this.driverClassName, true, this.driverClassLoader);@b@ }@b@ catch (ClassNotFoundException cnfe) {@b@ driverFromCCL = Thread.currentThread().getContextClassLoader().loadClass(this.driverClassName);@b@ }@b@ }@b@ catch (Throwable t)@b@ {@b@ String message = "Cannot load JDBC driver class '" + this.driverClassName + "'";@b@@b@ this.logWriter.println(message);@b@ t.printStackTrace(this.logWriter);@b@ throw new SQLNestedException(message, t);@b@ }@b@@b@ }@b@@b@ Driver driver = null;@b@ try {@b@ if (driverFromCCL == null) {@b@ driver = DriverManager.getDriver(this.url);@b@ }@b@ else@b@ {@b@ driver = (Driver)driverFromCCL.newInstance();@b@ if (!(driver.acceptsURL(this.url)))@b@ throw new SQLException("No suitable driver", "08001");@b@ }@b@ }@b@ catch (Throwable t) {@b@ String message = "Cannot create JDBC driver of class '" + ((this.driverClassName != null) ? this.driverClassName : "") + "' for connect URL '" + this.url + "'";@b@@b@ this.logWriter.println(message);@b@ t.printStackTrace(this.logWriter);@b@ throw new SQLNestedException(message, t);@b@ }@b@@b@ if (this.validationQuery == null) {@b@ setTestOnBorrow(false);@b@ setTestOnReturn(false);@b@ setTestWhileIdle(false);@b@ }@b@@b@ String user = this.username;@b@ if (user != null)@b@ this.connectionProperties.put("user", user);@b@ else {@b@ log("DBCP DataSource configured without a 'username'");@b@ }@b@@b@ String pwd = this.password;@b@ if (pwd != null)@b@ this.connectionProperties.put("password", pwd);@b@ else {@b@ log("DBCP DataSource configured without a 'password'");@b@ }@b@@b@ ConnectionFactory driverConnectionFactory = new DriverConnectionFactory(driver, this.url, this.connectionProperties);@b@ return driverConnectionFactory;@b@ }@b@@b@ protected void createConnectionPool()@b@ {@b@ GenericObjectPool gop;@b@ if ((this.abandonedConfig != null) && (this.abandonedConfig.getRemoveAbandoned())) {@b@ gop = new AbandonedObjectPool(null, this.abandonedConfig);@b@ }@b@ else@b@ gop = new GenericObjectPool();@b@@b@ gop.setMaxActive(this.maxActive);@b@ gop.setMaxIdle(this.maxIdle);@b@ gop.setMinIdle(this.minIdle);@b@ gop.setMaxWait(this.maxWait);@b@ gop.setTestOnBorrow(this.testOnBorrow);@b@ gop.setTestOnReturn(this.testOnReturn);@b@ gop.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);@b@ gop.setNumTestsPerEvictionRun(this.numTestsPerEvictionRun);@b@ gop.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);@b@ gop.setTestWhileIdle(this.testWhileIdle);@b@ this.connectionPool = gop;@b@ }@b@@b@ protected void createDataSourceInstance()@b@ throws SQLException@b@ {@b@ PoolingDataSource pds = new PoolingDataSource(this.connectionPool);@b@ pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());@b@ pds.setLogWriter(this.logWriter);@b@ this.dataSource = pds;@b@ }@b@@b@ protected void createPoolableConnectionFactory(ConnectionFactory driverConnectionFactory, KeyedObjectPoolFactory statementPoolFactory, AbandonedConfig configuration)@b@ throws SQLException@b@ {@b@ PoolableConnectionFactory connectionFactory = null;@b@ try {@b@ connectionFactory = new PoolableConnectionFactory(driverConnectionFactory, this.connectionPool, statementPoolFactory, this.validationQuery, this.validationQueryTimeout, this.connectionInitSqls, this.defaultReadOnly, this.defaultAutoCommit, this.defaultTransactionIsolation, this.defaultCatalog, configuration);@b@@b@ validateConnectionFactory(connectionFactory);@b@ } catch (RuntimeException e) {@b@ throw e;@b@ } catch (Exception e) {@b@ throw new SQLNestedException("Cannot create PoolableConnectionFactory (" + e.getMessage() + ")", e);@b@ }@b@ }@b@@b@ protected static void validateConnectionFactory(PoolableConnectionFactory connectionFactory) throws Exception {@b@ Connection conn = null;@b@ try {@b@ conn = (Connection)connectionFactory.makeObject();@b@ connectionFactory.activateObject(conn);@b@ connectionFactory.validateConnection(conn);@b@ connectionFactory.passivateObject(conn);@b@ }@b@ finally {@b@ connectionFactory.destroyObject(conn);@b@ }@b@ }@b@@b@ private void restart()@b@ {@b@ try@b@ {@b@ close();@b@ } catch (SQLException e) {@b@ log("Could not restart DataSource, cause: " + e.getMessage());@b@ }@b@ }@b@@b@ protected void log(String message) {@b@ if (this.logWriter != null)@b@ this.logWriter.println(message);@b@ }@b@@b@ static@b@ {@b@ DriverManager.getDrivers();@b@ }@b@}
2.BasicDataSourceFactory工厂类
package org.apache.tomcat.dbcp.dbcp;@b@@b@import java.io.ByteArrayInputStream;@b@import java.io.PrintStream;@b@import java.util.Collections;@b@import java.util.Enumeration;@b@import java.util.Hashtable;@b@import java.util.Properties;@b@import java.util.StringTokenizer;@b@import javax.naming.Context;@b@import javax.naming.Name;@b@import javax.naming.RefAddr;@b@import javax.naming.Reference;@b@import javax.naming.spi.ObjectFactory;@b@import javax.sql.DataSource;@b@@b@public class BasicDataSourceFactory@b@ implements ObjectFactory@b@{@b@ private static final String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";@b@ private static final String PROP_DEFAULTREADONLY = "defaultReadOnly";@b@ private static final String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";@b@ private static final String PROP_DEFAULTCATALOG = "defaultCatalog";@b@ private static final String PROP_DRIVERCLASSNAME = "driverClassName";@b@ private static final String PROP_MAXACTIVE = "maxActive";@b@ private static final String PROP_MAXIDLE = "maxIdle";@b@ private static final String PROP_MINIDLE = "minIdle";@b@ private static final String PROP_INITIALSIZE = "initialSize";@b@ private static final String PROP_MAXWAIT = "maxWait";@b@ private static final String PROP_TESTONBORROW = "testOnBorrow";@b@ private static final String PROP_TESTONRETURN = "testOnReturn";@b@ private static final String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";@b@ private static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";@b@ private static final String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";@b@ private static final String PROP_TESTWHILEIDLE = "testWhileIdle";@b@ private static final String PROP_PASSWORD = "password";@b@ private static final String PROP_URL = "url";@b@ private static final String PROP_USERNAME = "username";@b@ private static final String PROP_VALIDATIONQUERY = "validationQuery";@b@ private static final String PROP_VALIDATIONQUERY_TIMEOUT = "validationQueryTimeout";@b@ private static final String PROP_INITCONNECTIONSQLS = "initConnectionSqls";@b@ private static final String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";@b@ private static final String PROP_REMOVEABANDONED = "removeAbandoned";@b@ private static final String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";@b@ private static final String PROP_LOGABANDONED = "logAbandoned";@b@ private static final String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";@b@ private static final String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";@b@ private static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";@b@ private static final String[] ALL_PROPERTIES = { "defaultAutoCommit", "defaultReadOnly", "defaultTransactionIsolation", "defaultCatalog", "driverClassName", "maxActive", "maxIdle", "minIdle", "initialSize", "maxWait", "testOnBorrow", "testOnReturn", "timeBetweenEvictionRunsMillis", "numTestsPerEvictionRun", "minEvictableIdleTimeMillis", "testWhileIdle", "password", "url", "username", "validationQuery", "validationQueryTimeout", "initConnectionSqls", "accessToUnderlyingConnectionAllowed", "removeAbandoned", "removeAbandonedTimeout", "logAbandoned", "poolPreparedStatements", "maxOpenPreparedStatements", "connectionProperties" };@b@@b@ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment)@b@ throws Exception@b@ {@b@ if ((obj == null) || (!(obj instanceof Reference)))@b@ return null;@b@@b@ Reference ref = (Reference)obj;@b@ if (!("javax.sql.DataSource".equals(ref.getClassName()))) {@b@ return null;@b@ }@b@@b@ Properties properties = new Properties();@b@ for (int i = 0; i < ALL_PROPERTIES.length; ++i) {@b@ String propertyName = ALL_PROPERTIES[i];@b@ RefAddr ra = ref.get(propertyName);@b@ if (ra != null) {@b@ String propertyValue = ra.getContent().toString();@b@ properties.setProperty(propertyName, propertyValue);@b@ }@b@ }@b@@b@ return createDataSource(properties);@b@ }@b@@b@ public static DataSource createDataSource(Properties properties)@b@ throws Exception@b@ {@b@ BasicDataSource dataSource = new BasicDataSource();@b@ String value = null;@b@@b@ value = properties.getProperty("defaultAutoCommit");@b@ if (value != null) {@b@ dataSource.setDefaultAutoCommit(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("defaultReadOnly");@b@ if (value != null) {@b@ dataSource.setDefaultReadOnly(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("defaultTransactionIsolation");@b@ if (value != null) {@b@ int level = -1;@b@ if ("NONE".equalsIgnoreCase(value)) {@b@ level = 0;@b@ }@b@ else if ("READ_COMMITTED".equalsIgnoreCase(value)) {@b@ level = 2;@b@ }@b@ else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {@b@ level = 1;@b@ }@b@ else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {@b@ level = 4;@b@ }@b@ else if ("SERIALIZABLE".equalsIgnoreCase(value))@b@ level = 8;@b@ else@b@ try@b@ {@b@ level = Integer.parseInt(value);@b@ } catch (NumberFormatException e) {@b@ System.err.println("Could not parse defaultTransactionIsolation: " + value);@b@ System.err.println("WARNING: defaultTransactionIsolation not set");@b@ System.err.println("using default value of database driver");@b@ level = -1;@b@ }@b@@b@ dataSource.setDefaultTransactionIsolation(level);@b@ }@b@@b@ value = properties.getProperty("defaultCatalog");@b@ if (value != null) {@b@ dataSource.setDefaultCatalog(value);@b@ }@b@@b@ value = properties.getProperty("driverClassName");@b@ if (value != null) {@b@ dataSource.setDriverClassName(value);@b@ }@b@@b@ value = properties.getProperty("maxActive");@b@ if (value != null) {@b@ dataSource.setMaxActive(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("maxIdle");@b@ if (value != null) {@b@ dataSource.setMaxIdle(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("minIdle");@b@ if (value != null) {@b@ dataSource.setMinIdle(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("initialSize");@b@ if (value != null) {@b@ dataSource.setInitialSize(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("maxWait");@b@ if (value != null) {@b@ dataSource.setMaxWait(Long.parseLong(value));@b@ }@b@@b@ value = properties.getProperty("testOnBorrow");@b@ if (value != null) {@b@ dataSource.setTestOnBorrow(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("testOnReturn");@b@ if (value != null) {@b@ dataSource.setTestOnReturn(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("timeBetweenEvictionRunsMillis");@b@ if (value != null) {@b@ dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(value));@b@ }@b@@b@ value = properties.getProperty("numTestsPerEvictionRun");@b@ if (value != null) {@b@ dataSource.setNumTestsPerEvictionRun(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("minEvictableIdleTimeMillis");@b@ if (value != null) {@b@ dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(value));@b@ }@b@@b@ value = properties.getProperty("testWhileIdle");@b@ if (value != null) {@b@ dataSource.setTestWhileIdle(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("password");@b@ if (value != null) {@b@ dataSource.setPassword(value);@b@ }@b@@b@ value = properties.getProperty("url");@b@ if (value != null) {@b@ dataSource.setUrl(value);@b@ }@b@@b@ value = properties.getProperty("username");@b@ if (value != null) {@b@ dataSource.setUsername(value);@b@ }@b@@b@ value = properties.getProperty("validationQuery");@b@ if (value != null) {@b@ dataSource.setValidationQuery(value);@b@ }@b@@b@ value = properties.getProperty("validationQueryTimeout");@b@ if (value != null) {@b@ dataSource.setValidationQueryTimeout(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("accessToUnderlyingConnectionAllowed");@b@ if (value != null) {@b@ dataSource.setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("removeAbandoned");@b@ if (value != null) {@b@ dataSource.setRemoveAbandoned(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("removeAbandonedTimeout");@b@ if (value != null) {@b@ dataSource.setRemoveAbandonedTimeout(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("logAbandoned");@b@ if (value != null) {@b@ dataSource.setLogAbandoned(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("poolPreparedStatements");@b@ if (value != null) {@b@ dataSource.setPoolPreparedStatements(Boolean.valueOf(value).booleanValue());@b@ }@b@@b@ value = properties.getProperty("maxOpenPreparedStatements");@b@ if (value != null) {@b@ dataSource.setMaxOpenPreparedStatements(Integer.parseInt(value));@b@ }@b@@b@ value = properties.getProperty("initConnectionSqls");@b@ if (value != null) {@b@ StringTokenizer tokenizer = new StringTokenizer(value, ";");@b@ dataSource.setConnectionInitSqls(Collections.list(tokenizer));@b@ }@b@@b@ value = properties.getProperty("connectionProperties");@b@ if (value != null) {@b@ Properties p = getProperties(value);@b@ Enumeration e = p.propertyNames();@b@ while (e.hasMoreElements()) {@b@ String propertyName = (String)e.nextElement();@b@ dataSource.addConnectionProperty(propertyName, p.getProperty(propertyName));@b@ }@b@@b@ }@b@@b@ if (dataSource.getInitialSize() > 0) {@b@ dataSource.getLogWriter();@b@ }@b@@b@ return dataSource;@b@ }@b@@b@ private static Properties getProperties(String propText)@b@ throws Exception@b@ {@b@ Properties p = new Properties();@b@ if (propText != null)@b@ p.load(new ByteArrayInputStream(propText.replace(';', '\n').getBytes()));@b@@b@ return p;@b@ }@b@}