版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22271479/article/details/77621836
前言
JDBC连接池的存在,解决了数据库连接和释放资源的性能问题,通过在程序初始化的时候创建一定数量的连接,通过集合保存,每当需要进行数据库操作的时候,在连接池中拿,使用完毕后,不是释放资源而是在将拿出的连接对象放入集合中,这样就提高了性能。
通过装饰者模式来定义连接池
定义Connection实现
public class MyConnection implements Connection {
private Connection connection;
private LinkedList<Connection> linkedList;
public MyConnection(Connection connection, LinkedList<Connection> linkedList) {
this.connection = connection;
this.linkedList = linkedList;
}
@Override
public Statement createStatement() throws SQLException {
return connection.createStatement();
}
@Override
public void close() throws SQLException {
System.out.println("=========");
//将回收的Connection实例加进集合中
linkedList.addLast(connection);
}
......
......
}
定义DataSource实现的实现
/**
* Created by yzz on 2017/8/27.
* mail:[email protected]
*/
public class ConnectionPool_1 implements DataSource {
private static LinkedList<Connection> linkedList = new LinkedList<>();
static {
//类加载时创建一定数量的连接
initPool();
}
public static void initPool(){
for (int i = 0; i <5 ; i++) {
Connection connection = JDBCUtils.getConnection();
//将Connection对象进行装饰
MyConnection conn = new MyConnection(connection,linkedList);
//将装饰着的实例加入到集合中
linkedList.addFirst(conn);
}
}
@Override
public Connection getConnection() throws SQLException {
if (linkedList.size()==0){
initPool();
}
//访问一个连接,集合就要移除该连接
return linkedList.removeFirst();
}
public static void close(Connection connection){
if (connection==null)return;
try {
//调用的close方法是装饰过后的方法
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
......
......
}
通过动态代理来定义连接池
定义Connection实现
只需要实现close方法即可,只要当调用close方法时,才会去代理目标,其他方法代理不做任何事,还是交给目标Connection执行。
public class ConnectionProxy implements Connection{
private Connection connection;
private LinkedList<Connection> linkedList;
public ConnectionProxy(Connection connection, LinkedList<Connection> linkedList) {
this.connection = connection;
this.linkedList = linkedList;
}
@Override
public void close() throws SQLException {
System.out.println("=====================");
linkedList.addLast(connection);
}
......
......
}
动态代理,动态的去选择执行对象
/**
* Created by yzz on 2017/8/27.
* mail:[email protected]
* 1.传递一个目标对象和一个代理实现
* 2.当调用close方法时由代理对象执行,否则由目标对象执行
* 3.在invoke()的返回值就是方法调用的返回值,用户不能自己想当然,必须要严谨
*/
public class Connectionutils {
public static Connection getConn(Connection connection,Connection proxyConn){
Connection c = null;
try {
c = (Connection) Proxy.newProxyInstance(
connection.getClass().getClassLoader(),
new Class[]{Connection.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass());
if ("close".equals(method.getName())){
return method.invoke(proxyConn,args);
}else {
return method.invoke(connection,args);
}
}
}
);
}catch (Exception e){
e.printStackTrace();
}finally {
return c;
}
}
}
总结
通过装饰者模式和动态代理都优化了连接池操作,但是相比之下,还是动态代理更好,只需要根据需要来实现相关的方法,不需要重写接口中所有的方法。通过反射来判断当下执行的方法,动态的去选择执行者。