从一个ConnectionPool的实现看design pattern的运用 (source code for Java 1.1)

尹雅健
2023-12-01
ConnectionPool.java:

public interface ConnectionPool{
Connection getConnection()
throws test.res.ResourceNotAvailableException, SQLException;
Connection getConnection(long timeout)
throws test.res.ResourceTimeOutException, SQLException;
void clear();
}

ConnectionHome.java:

public interface ConnectionHome{
void releaseConnection(Connection conn);
}

ConnectionPooling.java:

public interface ConnectionPooling extends ConnectionHome{
Connection getConnection()
throws test.res.ResourceNotAvailableException, SQLException;

Connection getConnection(long timeout)
throws test.res.ResourceTimeOutException, SQLException;
void clear();
void releaseConnection(Connection conn);
}

ConnectionFactory.java:

public interface ConnectionFactory{
public Connection createConnection()throws SQLException;
}

PooledConnection.java: (for Connection in Java 1.1.8)


public final class PooledConnection implements Connection{
private interface ConnectionState{
ConnectionState close();
boolean isClosed();
Connection getOpenConnection()
throws SQLException;
}
private static class ClosedConnection implements ConnectionState{
public final ConnectionState close(){return this;}
public final Connection getOpenConnection()
throws SQLException{
throw new SQLException("Connection closed");
}
public final boolean isClosed(){return true;}
private ClosedConnection(){}
private static final ConnectionState _instance = new ClosedConnection();
static ConnectionState instance(Connection conn, ConnectionHome home){return _instance;}
}

private static class OpenConnection implements ConnectionState{
private final ConnectionHome home;
private final Connection conn;
public final ConnectionState close(){
home.releaseConnection(conn);
return ClosedConnection.instance(conn, home);
}
public final Connection getOpenConnection()
{return conn;}
public final boolean isClosed(){return false;}
OpenConnection(Connection conn, ConnectionHome home){
this.conn = conn; this.home = home;
}
static ConnectionState instance(Connection conn, ConnectionHome home){
return new OpenConnection(conn, home);
}
}
private ConnectionState state;
public static Connection decorate(Connection conn, ConnectionHome home)
throws SQLException{
return new PooledConnection(conn, home);
}

private PooledConnection(Connection conn, ConnectionHome home)
throws SQLException{
if(conn.isClosed()){
state = ClosedConnection.instance(conn, home);
}
else{
state = OpenConnection.instance(conn, home);
}
}
public final boolean isClosed(){
return state.isClosed();
}

public final void close(){
state = state.close();
}
protected void finalize(){
close();
}
private final Connection getOpenConnection()
throws SQLException
{return state.getOpenConnection();}
/*****then, delegate all the other methods****/
public final Statement createStatement()
throws SQLException{
return getOpenConnection().createStatement();
}

//....
public final void clearWarnings()throws SQLException{
getOpenConnection().clearWarnings();
}


public final void commit()throws SQLException{
getOpenConnection().commit();
}

/*
public final Statement createStatement(int resultSetType,
int resultSetConcurrency)
throws SQLException{
return getOpenConnection().createStatement(resultSetType, resultSetConcurrency);
}*/

/*
public final Statement createStatement(int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException{
return getOpenConnection().createStatement(resultSetType,
resultSetConcurrency, resultSetHoldability);
}*/


public final boolean getAutoCommit()throws SQLException{
return getOpenConnection().getAutoCommit();
}
public final String getCatalog()throws SQLException{
return getOpenConnection().getCatalog();
}
/*
public final int getHoldability()throws SQLException{
return getOpenConnection().getHoldability();
}*/

public final DatabaseMetaData getMetaData()throws SQLException{
return getOpenConnection().getMetaData();
}
public final int getTransactionIsolation()throws SQLException{
return getOpenConnection().getTransactionIsolation();
}
/*
public final Map getTypeMap()throws SQLException{
return getOpenConnection().getTypeMap();
}*/
public final SQLWarning getWarnings()throws SQLException{
return getOpenConnection().getWarnings();
}

public final boolean isReadOnly()throws SQLException{
return getOpenConnection().isReadOnly();
}
public final String nativeSQL(String sql)throws SQLException{
return getOpenConnection().nativeSQL(sql);
}
public final CallableStatement prepareCall(String sql)throws SQLException{
return getOpenConnection().prepareCall(sql);
}
/*
public final CallableStatement prepareCall(String sql,
int resultSetType, int resultSetConcurrency)
throws SQLException{
return getOpenConnection().prepareCall(sql, resultSetType, resultSetConcurrency);
}

public final CallableStatement prepareCall(String sql,
int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException{
return getOpenConnection().prepareCall(sql, resultSetType,
resultSetConcurrency, resultSetHoldability);
}*/

public final PreparedStatement prepareStatement(String sql)
throws SQLException{
return getOpenConnection().prepareStatement(sql);
}
/*
public final PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException{
return getOpenConnection().prepareStatement(sql, autoGeneratedKeys);
}

public final PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException{
return getOpenConnection().prepareStatement(sql, columnIndexes);
}

public final PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency)
throws SQLException{
return getOpenConnection().prepareStatement(sql,
resultSetType, resultSetConcurrency);
}

public final PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException{
return getOpenConnection().prepareStatement(sql,
resultSetType, resultSetConcurrency, resultSetHoldability);
}

public final PreparedStatement prepareStatement(String sql,
String[] columnNames)
throws SQLException{
return getOpenConnection().prepareStatement(sql, columnNames);
}

public final void releaseSavepoint(Savepoint savepoint)throws SQLException{
getOpenConnection().releaseSavepoint(savepoint);
}*/
public final void rollback()throws SQLException{
getOpenConnection().rollback();
}
/*
public final void rollback(Savepoint savepoint)
throws SQLException{
getOpenConnection().rollback(savepoint);
}*/

public final void setAutoCommit(boolean autoCommit)
throws SQLException{
getOpenConnection().setAutoCommit(autoCommit);
}

public final void setCatalog(String catalog)
throws SQLException{
getOpenConnection().setCatalog(catalog);
}
/*
public final void setHoldability(int holdability)
throws SQLException{
getOpenConnection().setHoldability(holdability);
}*/
public final void setReadOnly(boolean readOnly)
throws SQLException{
getOpenConnection().setReadOnly(readOnly);
}
/*
public final Savepoint setSavepoint()throws SQLException{
return getOpenConnection().setSavepoint();
}

public final Savepoint setSavepoint(String name)
throws SQLException{
return getOpenConnection().setSavepoint(name);
}*/

public final void setTransactionIsolation(int level)
throws SQLException{
getOpenConnection().setTransactionIsolation(level);
}
/*public final void setTypeMap(Map map)throws SQLException{
getOpenConnection().setTypeMap(map);

}*/

/*************************************************************************************************/


}

ConnectionPooling2Pool.java:

public class ConnectionPooling2Pool implements ConnectionPool{
public final Connection getConnection()
throws test.res.ResourceNotAvailableException, SQLException{
return PooledConnection.decorate(pooling.getConnection(), pooling);
}
public final Connection getConnection(long timeout)
throws test.res.ResourceTimeOutException, SQLException{
return PooledConnection.decorate(pooling.getConnection(timeout), pooling);
}
public final void clear(){
pooling.clear();
}
private final ConnectionPooling pooling;
private ConnectionPooling2Pool(ConnectionPooling pooling){
this.pooling = pooling;
}
public static ConnectionPool decorate(ConnectionPooling pooling){
return new ConnectionPooling2Pool(pooling);
}
}

ConnectionPoolingImpl.java: (a simple implementation of ConnectionMan)

public class ConnectionPoolingImpl implements ConnectionPooling
{
private int client=0;
private final Vector freeConn = new Vector();
private final int maxConn;
private final ConnectionFactory factory;

static public ConnectionPooling instance(ConnectionFactory factory, int max){
return new ConnectionPoolingImpl(factory, max);
}

private ConnectionPoolingImpl(ConnectionFactory factory, int max){
this.factory = factory;
this.maxConn = max;
}

public final synchronized void releaseConnection(Connection conn)
{
freeConn.addElement(conn);
client--;
notify();
}

public final synchronized Connection getConnection()
throws ResourceNotAvailableException, SQLException
{
Connection conn = null;
if(freeConn.size() > 0)
{
conn = (Connection)freeConn.lastElement();
freeConn.removeElementAt(freeConn.size()-1);
}
else if(client < maxConn)
{
conn = factory.createConnection();
}
if(conn != null)
{
client++;
return conn;
}
else
{
throw new ResourceNotAvailableException();
}
}

public final synchronized Connection getConnection(long timeout)
throws ResourceTimeOutException, SQLException
{
for(long startTime = new java.util.Date().getTime();;)
{
try
{
return getConnection();
}
catch(ResourceNotAvailableException e1)
{
try
{wait(timeout);
}
catch(InterruptedException e2)
{}
if((new java.util.Date().getTime() - startTime) >= timeout)
{
throw new ResourceTimeOutException();
}
}
}
}


public final synchronized int getfreeconn(){
return freeConn.size();
}
public final int getmaxConn(){
return maxConn;
}
public final synchronized int getclient(){
return client;
}
public final synchronized void setclient(){
client=0;
}

public final synchronized void clear(){
closeAll();
freeConn.removeAllElements();
}
private final void closeAll(){
for(int i=0; i<freeConn.size();i++)
{
final Connection conn = (Connection)freeConn.elementAt(i);
try{
conn.close();
}
catch(SQLException sqlException){}
}
}
protected void finalize(){
closeAll();
}
}

ConnectionFactoryImpl.java:

public class ConnectionFactoryImpl
{
private ConnectionFactoryImpl(){}
static public ConnectionFactory instance(final String driver, final String url,
final String user, final String pwd)
throws SQLException, ClassNotFoundException{
final Class driverClass = Class.forName(driver);
return new ConnectionFactory(){
private final Class keeper = driverClass;
public final Connection createConnection()
throws SQLException{
return DriverManager.getConnection(url,user,pwd);
}
};
}
static public ConnectionFactory instance(final String driver, final String url)
throws SQLException, ClassNotFoundException{
final Class driverClass = Class.forName(driver);
return new ConnectionFactory(){
private final Class keeper = driverClass;
public final Connection createConnection()
throws SQLException{
return DriverManager.getConnection(url);
}
};
}
}

TestConnectionPool.java:

public class TestConnectionPool{
public static void test(String driver, String url, String user, String pwd)
throws java.sql.SQLException, test.res.ResourceNotAvailableException, test.res.ResourceTimeOutException, ClassNotFoundException{
final ConnectionPool pool = ConnectionPooling2Pool.decorate(
ConnectionPoolingImpl.instance(
ConnectionFactoryImpl.instance(driver, url, user, pwd),
1000)
);
}
}

ResourceNotAvailableException.java:

public class ResourceNotAvailableException extends RuntimeException{
public ResourceNotAvailableException(String msg){super(msg);}
public ResourceNotAvailableException(){}
}

ResourceTimeOutException.java:

public class ResourceTimeOutException extends Exception{
public ResourceTimeOutException(String msg){super(msg);}
public ResourceTimeOutException(){}
}
 类似资料: