日期:2014-05-16  浏览次数:20478 次

动态代理实现dataSource ConnectionPool
编写连接池需实现java.sql.DataSource接口,
DataSource接口中定义了两个重载的getConnection方法:
Connection getConnection()
Connection getConnection(String username, String password)


没有close或release方法那么怎么 释放到池中呢?
所以通过动态代理实现
代码如下


public class JdbcPool implements DataSource {

	private static String driver;
	private static String url;
	private static  String username;
	private static String password;

	static{
		try {
			
			Properties prop = new Properties();
			InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("db.properties");
			prop.load(in);
			driver = prop.getProperty("driver");
			url = prop.getProperty("url");
			username = prop.getProperty("username");
			password = prop.getProperty("password");
			Class.forName(driver);
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	private static LinkedList<Connection> pool = new LinkedList<Connection>();
	private static int poolsize = 10;
	//问题:每次newJdbcPoll都会建立10个链接,可使用单态设计模式解决此类问题
	public JdbcPool(){
	
		for(int i=0;i<poolsize;i++){
			try {
				Connection conn = DriverManager.getConnection(url,username,password);
				pool.add(conn);
				System.out.println(conn + "被加到池里面了!!!");
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	/*
	 * 这里使用动态代理技术返回一个假的Connection,当dao调用假connection的任何方法时,该方法体内会调用InvocationHandler.invoke方法
	 * 在invoke方法体内,发现dao调用的是close方法,则把链接还到池里,否则,调用真connection的对应方法。
	 * (non-Javadoc)
	 * @see javax.sql.DataSource#getConnection()
	 */
	public Connection getConnection() throws SQLException { //spring aop
		if(pool.size()>0){
			final Connection conn = pool.removeFirst();
			System.out.println(conn + "从池里面取出去了!!!");
			return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(),conn.getClass().getInterfaces(), new InvocationHandler(){
					//proxy为代理对象 method为要调用的方法 args为方法的参数
				public Object invoke(Object proxy, Method method, Object[] args)
						throws Throwable {
					if(method.getName().equals("close")){
						pool.addFirst(conn);
						System.out.println(conn + "被还到池里面了!!");
						return null;
					}else{
						return method.invoke(conn, args);
					}
				}
			});
			
		}
		throw new RuntimeException("对不起,池里没有资源了!!!");
	}

	public Connection getConnection(String arg0, String arg1)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	public PrintWriter getLogWriter() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	public int getLoginTimeout() throws SQLException {
		// TODO Auto-generated method stub
		return 0;
	}

	public void setLogWriter(PrintWriter arg0) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setLoginTimeout(int arg0) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	//public Jdbcpool
	
}