代码从DataSourceFactory-》DataSource-》ConnectionPool-》PooledConnection 配置:
<GlobalNamingResources> ... <Resource name="sharedDataSource" global="sharedDataSource" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" alternateUsernameAllowed="true" username="bar" password="barpass" ... ... </GlobalNamingResources> DataSourceFactory实现javax.naming.spi.ObjectFactory,在getObjectInstance方法中创建DataSource public DataSource createDataSource(Properties properties,Context context, boolean XA) throws Exception { PoolConfiguration poolProperties = DataSourceFactory.parsePoolProperties(properties); if (poolProperties.getDataSourceJNDI()!=null && poolProperties.getDataSource()==null) { performJNDILookup(context, poolProperties); } org.apache.tomcat.jdbc.pool.DataSource dataSource = XA? new org.apache.tomcat.jdbc.pool.XADataSource(poolProperties) : new org.apache.tomcat.jdbc.pool.DataSource(poolProperties); //initialise the pool itself dataSource.createPool(); // Return the configured DataSource instance return dataSource; } DataSource创建ConnectionPool public ConnectionPool createPool() throws SQLException { if (pool != null) { return pool; } else { return pCreatePool(); } } /** * Sets up the connection pool, by creating a pooling driver. */ private synchronized ConnectionPool pCreatePool() throws SQLException { if (pool != null) { return pool; } else { pool = new ConnectionPool(poolProperties); return pool; } } ConnectionPool根据配置初始化连接 //initialize the pool with its initial set of members PooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()]; try { for (int i = 0; i < initialPool.length; i++) { initialPool[i] = this.borrowConnection(0, null, null); //don't wait, should be no contention } //for } catch (SQLException x) { log.error("Unable to create initial connections of pool.", x); if (!poolProperties.isIgnoreExceptionOnPreLoad()) { if (jmxPool!=null) jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.NOTIFY_INIT, getStackTrace(x)); close(true); throw x; } } finally { //return the members as idle to the pool for (int i = 0; i < initialPool.length; i++) { if (initialPool[i] != null) { try {this.returnConnection(initialPool[i]);}catch(Exception x){/*NOOP*/} } //end if } //for } //catch ConnectionPool的getConnection方法获取数据库连接 public Connection getConnection() throws SQLException { //从线程池中获取连接 PooledConnection con = borrowConnection(-1,null,null); return setupConnection(con); } //将获取的PooledConnection包裹一层代理 protected Connection setupConnection(PooledConnection con) throws SQLException { //fetch previously cached interceptor proxy - one per connection JdbcInterceptor handler = con.getHandler(); if (handler==null) { //为PooledConnection包层代理 //ProxyConnection实现了InvocationHandler接口 handler = new ProxyConnection(this,con,getPoolProperties().isUseEquals()); //set up the interceptor chain PoolProperties.InterceptorDefinition[] proxies = getPoolProperties().getJdbcInterceptorsAsArray(); for (int i=proxies.length-1; i>=0; i--) { try { //create a new instance JdbcInterceptor interceptor = proxies[i].getInterceptorClass().newInstance(); //configure properties interceptor.setProperties(proxies[i].getProperties()); //setup the chain interceptor.setNext(handler); //call reset interceptor.reset(this, con); //configure the last one to be held by the connection handler = interceptor; }catch(Exception x) { SQLException sx = new SQLException("Unable to instantiate interceptor chain."); sx.initCause(x); throw sx; } } //cache handler for the next iteration con.setHandler(handler); } else { JdbcInterceptor next = handler; //we have a cached handler, reset it while (next!=null) { next.reset(this, con); next = next.getNext(); } } // setup statement proxy if (getPoolProperties().getUseStatementFacade()) { handler = new StatementFacade(handler); } try { //动态生成代理类 getProxyConstructor(con.getXAConnection() != null); //创建代理类 Connection connection = null; if (getPoolProperties().getUseDisposableConnectionFacade() ) { connection = (Connection)proxyClassConstructor.newInstance(new Object[] { new DisposableConnectionFacade(handler) }); } else { connection = (Connection)proxyClassConstructor.newInstance(new Object[] {handler}); } //return the connection return connection; }catch (Exception x) { SQLException s = new SQLException(); s.initCause(x); throw s; } } public Constructor<?> getProxyConstructor(boolean xa) throws NoSuchMethodException { //cache the constructor if (proxyClassConstructor == null ) { Class<?> proxyClass = xa ? Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class, javax.sql.XAConnection.class}) : Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class}); proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class }); } return proxyClassConstructor; }