diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataAbstractSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataAbstractSource.java index 8274e0e09d..45f3065afd 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataAbstractSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataAbstractSource.java @@ -98,7 +98,7 @@ public abstract class DruidDataAbstractSource implements DataSource, DataSourceP protected PrintWriter logWriter = new PrintWriter(System.out); - private List filters = new ArrayList(); + protected List filters = new ArrayList(); protected Driver driver; diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 8a8557bba0..bcdb4c01c3 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; import java.util.Set; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -33,6 +34,7 @@ import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; +import com.alibaba.druid.filter.Filter; import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig; import com.alibaba.druid.util.JdbcUtils; @@ -72,6 +74,8 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat private final IdentityHashMap activeConnections = new IdentityHashMap(); + private final CountDownLatch initedLatch = new CountDownLatch(2); + public DruidDataSource(){ } @@ -81,14 +85,6 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat } try { - final int maxWaitThreadCount = getMaxWaitThreadCount(); - if (maxWaitThreadCount > 0) { - if (lock.getQueueLength() > maxWaitThreadCount) { - throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count " - + lock.getQueueLength()); - } - } - lock.lockInterruptibly(); if (inited) { @@ -116,6 +112,10 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat } catch (ClassNotFoundException e) { throw new SQLException(e.getMessage(), e); } + + for (Filter filter : filters) { + filter.init(this); + } initConnectionFactory(); @@ -145,7 +145,12 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat createConnectionThread.start(); destoryConnectionThread.start(); + initedLatch.await(); inited = true; + + if (count == 0) { + lowWater.signal(); + } } catch (InterruptedException e) { throw new SQLException(e.getMessage(), e); } finally { @@ -193,6 +198,14 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat public Connection getConnection() throws SQLException { init(); + final int maxWaitThreadCount = getMaxWaitThreadCount(); + if (maxWaitThreadCount > 0) { + if (lock.getQueueLength() > maxWaitThreadCount) { + throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count " + + lock.getQueueLength()); + } + } + try { lock.lockInterruptibly(); @@ -380,6 +393,10 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat try { while (count == 0) { + if (minIdle == 0) { + lowWater.signal(); + } + notEmpty.await(); } } catch (InterruptedException ie) { @@ -475,11 +492,15 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat } public void run() { + initedLatch.countDown(); + for (;;) { // addLast lock.lock(); try { - if (count >= minIdle) { + if (count == 0 && minIdle == 0 && lock.getWaitQueueLength(notEmpty) > 0) { + // not wait + } else if (count >= minIdle) { lowWater.await(); } @@ -509,6 +530,8 @@ public class DruidDataSource extends DruidDataAbstractSource implements DruidDat } public void run() { + initedLatch.countDown(); + for (;;) { // 从前面开始删除 try { diff --git a/src/main/java/com/alibaba/druid/util/JdbcUtils.java b/src/main/java/com/alibaba/druid/util/JdbcUtils.java index c110c77edc..583b3e434f 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcUtils.java +++ b/src/main/java/com/alibaba/druid/util/JdbcUtils.java @@ -348,7 +348,7 @@ public final class JdbcUtils { return "com.microsoft.jdbc.sqlserver.SQLServerDriver"; } else if (rawUrl.startsWith("jdbc:jtds:")) { return "net.sourceforge.jtds.jdbc.Driver"; - } else if (rawUrl.startsWith("jdbc:fake:")) { + } else if (rawUrl.startsWith("jdbc:fake:") || rawUrl.startsWith("jdbc:mock:")) { return "com.alibaba.druid.mock.MockDriver"; } else if (rawUrl.startsWith("jdbc:postgresql:")) { return "org.postgresql.Driver"; diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java index 29b0151115..95525beb51 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java @@ -1,9 +1,13 @@ package com.alibaba.druid.bvt.pool; +import java.sql.Connection; + import junit.framework.Assert; import junit.framework.TestCase; import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.stat.JdbcConnectionStat; +import com.alibaba.druid.stat.JdbcStatManager; public class DruidDataSourceFilterTest extends TestCase { @@ -26,4 +30,22 @@ public class DruidDataSourceFilterTest extends TestCase { Assert.assertEquals(2, dataSource.getFilters().size()); } + + public void test_filter_3() throws Exception { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:"); + + Assert.assertEquals(0, dataSource.getFilters().size()); + + dataSource.setFilters("stat"); + + JdbcStatManager.getInstance().reset(); + + Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + Assert.assertEquals(1, dataSource.getFilters().size()); + + Connection conn = dataSource.getConnection(); + + Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + } }