本文主要是介绍动态代理在JDBC的DataSource中的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目的:为数据连接池中的每一个Connection创建一个代理,当需要使用Connection对象操作数据库时,先判断是否超过连接池的最大连接数,如果没有超过,取得连接,否则不进行连接。
1、抽象对象角色
JDBC提供了Connection接口
2、定义我们自己的数据连接池,实现DataSource接口
public class MyDataSource implements DataSource{private static String url = "jdbc:mysql://localhost:3306/jdbc";private static String user = "root";private static String password = "";private static int initCount = 1;private static int maxCount = 1;int currentCount = 0;LinkedList<Connection> connectionsPool = new LinkedList<Connection>();public MyDataSource() {try {for (int i = 0; i < initCount; i++) {this.connectionsPool.addLast(this.createConnection());this.currentCount++;}} catch (SQLException e) {throw new ExceptionInInitializerError(e);}}public Connection getConnection() throws SQLException {synchronized (connectionsPool) {if (this.connectionsPool.size() > 0)return this.connectionsPool.removeFirst();if (this.currentCount < maxCount) {this.currentCount++;return this.createConnection();}throw new SQLException("服务器连接异常");}}public void free(Connection conn) {this.connectionsPool.addLast(conn);}private Connection createConnection() throws SQLException {Connection realConn = DriverManager.getConnection(url, user, password); //真实对象MyConnectionHandler proxy = new MyConnectionHandler(this); //代理处理器return proxy.bind(realConn); //创建代理对象}public Connection getConnection(String username, String password)throws SQLException {return null;}public PrintWriter getLogWriter() throws SQLException {return null;}public int getLoginTimeout() throws SQLException {return 0;}public void setLogWriter(PrintWriter out) throws SQLException {}public void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}
}
3、定义动态代理处理类,实现InvocationHandler接口
class MyConnectionHandler implements InvocationHandler {private Connection realConnection;private Connection warpedConnection;private MyDataSource dataSource;private int maxUseCount = 5;private int currentUserCount = 0;MyConnectionHandler(MyDataSource2 dataSource) {this.dataSource = dataSource;}//注意:不一定非要在该类中创建代理,只要在创建代理的时候传入一个MyConnectionHandler类的实例就可以了Connection bind(Connection realConn) {this.realConnection = realConn;this.warpedConnection = (Connection) Proxy.newProxyInstance(this.realConnection .getClass().getClassLoader(), new Class[] { Connection.class },this); //创建代理对象return warpedConnection;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (!"close".equals(method.getName())) {//非关闭连接操作this.currentUserCount++;if (this.currentUserCount <= this.maxUseCount) //只有在这个类中进行判断后才进行连接,减轻了服务器的压力return method.invoke(this.realConnection, args);}else {this.realConnection.close();this.dataSource.currentCount--;}return null;}
}
这篇关于动态代理在JDBC的DataSource中的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!