在練習資料庫連接配接池時,遇到一個問題,之前同樣使用過代理,方式一樣都沒有問題,代碼如下。
final Connection conn = pool.remove(0);
//--利用動态代理改造close方法
Connection proxy = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces()
, new InvocationHandler(){
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
if("close".equals(method.getName())){
//對于想要改造的close方法,我們自己寫
retConn(conn);
return null;
}else{
//對于不想改造的方法調用被代理者身上相同的方法
return method.invoke(conn, args);
}
}
});
運作時出現異常: $Proxy0 cannot be cast to java.sql.Connection
一直解決不了,上網查了下,原來Connection.getInterfaces() 與資料庫驅動有關,資料庫驅動不同 Connection.getInterfaces() 的結果也就不同,Connection.getInterfaces() 傳回的是 Class[] 數組,此數組的第一個元素必須是Connection才能把建立的代理類轉為Connection對象,否則就會報:java.lang.ClassCastException。
因為Connection本身就是一個接口,它的位元組碼符合第二個參數要求,于是把conn.getClass().getInterfaces();改成new Class[]{Connection.class},問題就解決了