關於利用動態代理手寫資料庫連線池的異常 java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection

破玉發表於2016-04-09

程式碼如下

final Connection conn=pool.remove(0);
            
            //利用動態代理改造close方法
    Connection  proxy= (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {
                
                @Override
                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);
                    }
                }
            });

異常如下:

 

java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection

 

原因分析:

這個異常出現的原因在於我使用的mysql資料庫驅動的問題,由於資料庫驅動不同,Connection.class.getInterfaces()返回的結果也不同,它返回的是一個Class[]陣列,然而此陣列的第一個元素必須是Connection才能把建立的代理類轉為Connection物件,否則就會報錯。

所以這裡我們可以採取一個替代方式替換Connection.class.getInterfaces(),即new Class[] { Connection.class },這樣無論資料庫驅動是什麼版本的驅動,都能保證這個型別轉換不出錯。

參考文章:點我呀

使勁點我呀

相關文章