JDK API动态代理模拟数据库连接池
实现:在MyDataSource类中,编写静态方法getConnection,使该方法能够返回一个Connection的代理对象,该代理对象对Connection的close方法进行增强,使close方法不再直接关闭数据库连接而是将数据库连接返回到MyDataSource的连接池(链表或是其他的数据结构)中。
这样,外部通过MyDataSource获取Connection代理对象,外部调用Connection代理对象的close方法,即可将Connection对象归还到MyDataSource的连接池中。
PS:
MyDataSourceAdapter.java可有可无,不使用MyDataSourceAdapter.java的话,请在MyDataSource.java中实现DataSource接口
MyDataSourceAdapter.java
package DataSrouceTest;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import javax.sql.DataSource;
public abstract class MyDataSourceAdapter implements DataSource {
@Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
MyDataSource.java
package DataSrouceTest;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
public class MyDataSource extends MyDataSourceAdapter {
private static LinkedList<Connection> pool;
private static final int DEFAULT_SIZE = 5;
private static String username;
private static String password;
private static String url;
static {
pool = new LinkedList<Connection>();
Properties prop = new Properties();
try {
prop.load(MyDataSource.class.getClassLoader().getResourceAsStream("db_server.properties"));
username = prop.getProperty("username");
password = prop.getProperty("password");
url = prop.getProperty("url");
try {
Class.forName(prop.getProperty("driverClassName"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < DEFAULT_SIZE; i++) {
try {
pool.add(DriverManager.getConnection(url, username, password));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 返回一个Connection的代理对象
*/
@Override
public Connection getConnection() throws SQLException {
Connection connection = pool.remove();
System.out.println("数据库连接被借走,当前数据库连接池中连接数为:" + pool.size());
Connection proxy = (Connection) Proxy.newProxyInstance(connection.getClass().getClassLoader(),
new Class<?>[] { Connection.class }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("close".equals(method.getName())) {
pool.add(connection);
System.out.println("数据库连接被归还,当前数据库连接池中连接数为:" + pool.size());
return null;
} else {
return method.invoke(connection, args);
}
}
});
return proxy;
}
}