在练习数据库连接池时,遇到一个问题,之前同样使用过代理,方式一样都没有问题,代码如下。
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},问题就解决了