diff --git a/src/main/java/com/alibaba/druid/filter/Filter.java b/src/main/java/com/alibaba/druid/filter/Filter.java index 7419fe9bf4..f1bf13ee79 100644 --- a/src/main/java/com/alibaba/druid/filter/Filter.java +++ b/src/main/java/com/alibaba/druid/filter/Filter.java @@ -44,6 +44,8 @@ import java.sql.Wrapper; import java.util.Calendar; import java.util.Properties; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.config.AbstractDruidFilterConfig; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.ClobProxy; @@ -1278,4 +1280,8 @@ public interface Filter { // ///////// void loadConfig(AbstractDruidFilterConfig druidFilterConfig); + + void dataSource_recycle(FilterChain chain, DruidPooledConnection connection) throws SQLException; + + DruidPooledConnection dataSource_connect(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException; } diff --git a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java index 294116e544..86c6c3d5f6 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java @@ -42,6 +42,8 @@ import java.util.Properties; import javax.management.NotificationBroadcasterSupport; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.config.AbstractDruidFilterConfig; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.ClobProxy; @@ -57,6 +59,7 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy; * @author wenshao */ public abstract class FilterAdapter extends NotificationBroadcasterSupport implements Filter { + protected DataSourceProxy dataSource; @Override @@ -67,10 +70,10 @@ public abstract class FilterAdapter extends NotificationBroadcasterSupport imple public void init(DataSourceProxy dataSource) { this.dataSource = dataSource; } - + @Override public void destory() { - + } @Override @@ -2700,4 +2703,13 @@ public abstract class FilterAdapter extends NotificationBroadcasterSupport imple // /////////////////// + @Override + public void dataSource_recycle(FilterChain chain, DruidPooledConnection connection) throws SQLException { + chain.dataSource_recycle(connection); + } + + @Override + public DruidPooledConnection dataSource_connect(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException { + return chain.dataSource_connect(dataSource, maxWaitMillis); + } } diff --git a/src/main/java/com/alibaba/druid/filter/FilterChain.java b/src/main/java/com/alibaba/druid/filter/FilterChain.java index e99bbe1a93..436b87e24a 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterChain.java +++ b/src/main/java/com/alibaba/druid/filter/FilterChain.java @@ -41,6 +41,8 @@ import java.sql.Wrapper; import java.util.Calendar; import java.util.Properties; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.ClobProxy; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; @@ -52,7 +54,7 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy; * @author wenshao */ public interface FilterChain { - + int getFilterSize(); FilterChain cloneChain(); @@ -1174,4 +1176,8 @@ public interface FilterChain { public void clob_truncate(ClobProxy wrapper, long len) throws SQLException; // //// + + void dataSource_recycle(DruidPooledConnection connection) throws SQLException; + + DruidPooledConnection dataSource_connect(DruidDataSource dataSource, long maxWaitMillis) throws SQLException; } diff --git a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java index 5a917c7b05..522cf5f7c8 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java +++ b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.CallableStatementProxyImpl; import com.alibaba.druid.proxy.jdbc.ClobProxy; @@ -4390,4 +4392,14 @@ public class FilterChainImpl implements FilterChain { return new NClobProxyImpl(dataSource, connection, nclob); } + @Override + public void dataSource_recycle(DruidPooledConnection connection) throws SQLException { + connection.recycle(); + } + + @Override + public DruidPooledConnection dataSource_connect(DruidDataSource dataSource, long maxWaitMillis) throws SQLException { + return dataSource.getConnectionDirect(maxWaitMillis); + } + } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index ad89f7f2cb..17fdab3194 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -40,6 +40,7 @@ import javax.sql.ConnectionEventListener; import com.alibaba.druid.TransactionTimeoutException; import com.alibaba.druid.VERSION; import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.FilterChainImpl; import com.alibaba.druid.mock.MockDriver; import com.alibaba.druid.pool.DruidPooledPreparedStatement.PreparedStatementKey; import com.alibaba.druid.pool.vendor.InformixExceptionSorter; @@ -296,7 +297,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (this.dbType == null || this.dbType.length() == 0) { this.dbType = JdbcUtils.getDbType(jdbcUrl, driverClass.getClass().getName()); } - + if ("oracle".equals(this.dbType)) { isOracle = true; @@ -331,9 +332,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) { this.exceptionSorter = new MockExceptionSorter(); } - + dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl); - + { String property = System.getProperty("druid.filters"); if (property != null && property.length() > 0) { @@ -389,13 +390,22 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } @Override - public Connection getConnection() throws SQLException { + public DruidPooledConnection getConnection() throws SQLException { return getConnection(maxWait); } - public Connection getConnection(long maxWaitMillis) throws SQLException { + public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException { init(); + if (filters.size() > 0) { + FilterChainImpl filterChain = new FilterChainImpl(this); + return filterChain.dataSource_connect(this, maxWaitMillis); + } else { + return getConnectionDirect(maxWaitMillis); + } + } + + public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException { final int maxWaitThreadCount = getMaxWaitThreadCount(); if (maxWaitThreadCount > 0) { if (notEmptyWaitThreadCount > maxWaitThreadCount) { @@ -779,7 +789,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat ConnectionHolder pollLast(long timeout, TimeUnit unit) throws InterruptedException, SQLException { long estimate = unit.toNanos(timeout); - for (int i = 0;;++i) { + for (int i = 0;; ++i) { if (poolingCount == 0) { empty.signal(); // send signal to CreateThread create connection @@ -1377,21 +1387,21 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat public String getVersion() { return VERSION.getVersionNumber(); } - + @Override public JdbcDataSourceStat getDataSourceStat() { return dataSourceStat; } - + public Object clone() throws CloneNotSupportedException { return cloneDruidDataSource(); } public DruidDataSource cloneDruidDataSource() { DruidDataSource x = new DruidDataSource(); - + cloneTo(x); - + return x; } } diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java index 098277512b..6e786fe102 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java @@ -31,6 +31,7 @@ import java.sql.SQLXML; import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; @@ -39,6 +40,8 @@ import javax.sql.ConnectionEvent; import javax.sql.ConnectionEventListener; import javax.sql.StatementEventListener; +import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.FilterChainImpl; import com.alibaba.druid.pool.DruidPooledPreparedStatement.PreparedStatementKey; import com.alibaba.druid.pool.PreparedStatementPool.MethodType; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; @@ -156,12 +159,11 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec @Override public void close() throws SQLException { - ConnectionHolder holder = this.holder; - if (this.diable) { return; } + ConnectionHolder holder = this.holder; if (holder == null && dupCloseLogEnable) { LOG.error("dup close"); return; @@ -171,6 +173,27 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec listener.connectionClosed(new ConnectionEvent(this)); } + DruidAbstractDataSource dataSource = holder.getDataSource(); + List filters = dataSource.getProxyFilters(); + if (filters.size() > 0) { + FilterChainImpl filterChain = new FilterChainImpl(dataSource); + filterChain.dataSource_recycle(this); + } else { + recycle(); + } + } + + public void recycle() throws SQLException { + if (this.diable) { + return; + } + + ConnectionHolder holder = this.holder; + if (holder == null && dupCloseLogEnable) { + LOG.error("dup close"); + return; + } + holder.getDataSource().recycle(this); this.holder = null; @@ -211,7 +234,7 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec return rtnVal; } - + private void initStatement(PreparedStatementHolder stmtHolder) throws SQLException { stmtHolder.incrementInUseCount(); holder.getDataSource().initStatement(this, stmtHolder.getStatement());