我想写一个数据库连接池来为其他数据库访问类提供Connection, 但是我这个数据库连接池的产生是在数据库访问类写完之后, 因此所有的访问在结尾都有Connection.close()的调用, 因此我就在想, 当调用connection.close()时, 将该connection加入数据库连接池中. 所以我就写了一个代理类, 但是想的很美, 写起来就不知道该怎么写了. 如何将这个proxy产生的代理对象加入连接池中呢?
我目前的实现如下:
class EmptyInvocationHandler implements InvocationHandler{ private EmptyConnection emptyConnection ; private ConnectionPool connectionPool ; public EmptyInvocationHandler(EmptyConnection emptyConnection ,ConnectionPool connectionPool) { this.connectionPool = connectionPool ; this.emptyConnection = emptyConnection; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("close")){ close(); return null ; } else return method.invoke(emptyConnection , args) ; } //如果这样实现的话, 就是把真实的对象加入了连接池中, 如何把这个代理对象加入池中呢? private void close(){ connectionPool.recycleConnection(emptyConnection); } } //模拟Connecter接口 interface EmptyConnectionI{ void doSomething() ; void close() ; } //connecter的默认实现 class EmptyConnection implements EmptyConnectionI{ public void doSomething(){ System.out.println("do something"); } public void close(){ System.out.println("real close"); } } class ConnectionPool{ private List<EmptyConnectionI> list = new ArrayList<>() ; private boolean inited = false ; public EmptyConnectionI getConnection(){ if(!inited) init() ; return list.remove(0) ; } private void init(){ EmptyConnection emptyConnection = new EmptyConnection() ; try { Class proxyClass = Proxy.getProxyClass(EmptyConnection.class.getClassLoader() , new Class[]{EmptyConnectionI.class}); EmptyConnectionI emptyConnectionI = (EmptyConnectionI) proxyClass.getConstructor(new Class[]{InvocationHandler.class}) .newInstance(new EmptyInvocationHandler(emptyConnection, this)); list.add(emptyConnectionI) ; } catch (Exception e){ e.printStackTrace(); System.exit(-1); } } public void recycleConnection(EmptyConnectionI connection){ list.add(connection) ; } }
可以实现的,MyBatis的PooledConnection和PooledDataSource这两个类就做了这样的事情,先标个记,回头写篇这两个类的源码分析文章再贴回来。