1. 程式人生 > >Java 的動態代理例項(JDBC的資料庫的連線池(DataSource))

Java 的動態代理例項(JDBC的資料庫的連線池(DataSource))

問題:以下兩種方式的區別是什麼?

//註冊資料庫的驅動

Class.forName(driver);

//還有一種方式

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());


==================================================================

package demo.proxy.datasource;


import java.io.PrintWriter;
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.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;


import javax.sql.DataSource;


public class MyDataSourcePool implements DataSource {

//初始化該連線池,放入10個連結
private static String driver = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://192.168.157.111:3306/hive";
private static String user = "hiveowner";
private static String password ="Welcome_1";

//定義一個連結串列代表連線池
private static LinkedList<Connection> dataSource = new LinkedList<>();

static{
try{
//註冊資料庫的驅動
Class.forName(driver);

//還有一種方式
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());

//初始化10個連結
for(int i=0;i<10;i++){
dataSource.add(DriverManager.getConnection(url, user, password));
}
}catch(Exception ex){
ex.printStackTrace();
}
}



@Override
public Connection getConnection() throws SQLException {
// 返回一個連線給客戶端
if(dataSource.size() > 0){
//存在連結
//真正的物件
final Connection conn = dataSource.removeFirst();

//生成真正物件的代理物件,重寫close方法,還給連線池
Connection proxyConn = (Connection) Proxy.newProxyInstance(MyDataSourcePool.class.getClassLoader(), 
              conn.getClass().getInterfaces(), 
              new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 重寫close方法
if(method.getName().equals("close")){
//呼叫了close方法 將該連結返回給連線池
dataSource.add(conn);
return null;
}else{
//呼叫了其他方法
return method.invoke(conn, args);
}
}
});

return proxyConn;
}else{
//沒有連結
throw new SQLException("系統忙,請稍後.....");
}
}



@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;
}


}

==================================================================

package demo.proxy.datasource;


import java.sql.Connection;




public class TestDataSource {


public static void main(String[] args) throws Exception {
// 測試連線池
MyDataSourcePool ds = new MyDataSourcePool();


//取出連結使用
for(int i=0; i<11;i++){
Connection conn = ds.getConnection();

System.out.println("第"+i+"個連結:" + conn);

//關閉connection
conn.close();
}
}


}