return Proxy.newProxyInstance(connection.getClass().getClassLoader(), Connection.class.getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; if(method.getName().equals("close")){ //获取连接池 Set<Connection> set = DBCPMyPoolUtil.getSet(); if(set.size()< maxIdle){ //检查连接数是否达到最大保存连接数值 //如果没有达到可保存数,将连接放入连接池 set.add(connection); System.out.println("回收连接: "+connection); } else { //如何连接数达到最大保存值,直接用close方法关闭连接,该连接不再被重复使用,更不会被保存到连接池中 if(connection!=null){ //此时method方法为close直接关闭method result = method.invoke(connection,args); } System.out.println("关闭conn: "+connection); } int active = DBCPMyPoolUtil.getActive(); active--; DBCPMyPoolUtil.setActive(active); } else { result = method.invoke(connection,args); } return result; } });
报错:java.lang.ClassCastException: com.sun.proxy.$Proxy4 cannot be cast to java.sql.Connection
在使用动态代理增强Connection连接对象的close方法时,我碰到了如题所示的异常。通过搜索我发现这个异常出现的原因在于我使用的mysql数据库驱动的问题,由于数据库驱动不同,Connection.class.getInterfaces()返回的结果也不同,它返回的是一个Class[]数组,然而此数组的第一个元素必须是Connection才能把创建的代理类转为Connection对象,否则就会报错。
解决方案: 所以这里我们可以采取一个替代方式替换Connection.class.getInterfaces(),即new Class[] { Connection.class },这样无论数据库驱动是什么版本的驱动,都能保证这个类型转换不出错。
return Proxy.newProxyInstance(connection.getClass().getClassLoader(), new Class[] { Connection.class }, new InvocationHandler() { ... }