解决Proxy.newProxyInstance创建动态代理导致类型转换错误的问题
来源:互联网 发布:山东知乎 编辑:程序博客网 时间:2024/04/25 02:25
在使用Proxy.newProxyInstance创建动态代理时,有时会导致类型转换错误。
package cn.itcast.demo;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import javax.sql.DataSource;
import com.mysql.jdbc.Connection;
public class JdbcPool implements DataSource {
private static LinkedList<Connection> list = new LinkedList<Connection>();
static{
try{
InputStream in = JdbcPool.class.getClassLoader().getResourceAsStream("driver.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
Class.forName(driver);
for(int i=0;i<10;i++){
Connection conn = (Connection) DriverManager.getConnection(url, username, password);
list.add(conn);
}
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
/*
1.写一个子类,覆盖close方法
2、写一个connection的包装类,增强close方法
3、用动态代理,返回一个代理对象出去,拦截close方法的调用,对close进行增强
*/
public Connection getConnection() throws SQLException {
if(list.size()>0){
final Connection conn = list.removeFirst();
Object obj;
obj = Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(!method.getName().equals("close")){
return method.invoke(conn, args);
}else{
list.add(conn);
return null;
}
}
});
return (Connection)obj;
}else{
throw new RuntimeException();
}
}
...
}
此处将会导致类型转换异常:
java.lang.ClassCastException: $Proxy4 cannot be cast to com.mysql.jdbc.Connection
at cn.itcast.utils.JdbcDyPools.getConnection(JdbcDyPools.java:66)
要想分析其原因,还需要对Proxy.newProxyInstance方法进行了解,其原型为
java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h) throwsIllegalArgumentException
它创建的代理实现了interfaces接口,由于conn.getClass().getInterfaces()获取到的接口数组是com.mysql.jdbc.Connection继承的接口,所以得到的结果是java.sql.Connection,但是这里需要使用com.mysql.jdbc.Connection;所以导致转换错误两种解决方法:
1、将代码中的Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), hander);改写为:
Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), new Class[]{com.mysql.jdbc.Connection.class}, hander);
2、创建一个接口继承com.mysql.jdbc.Connection
interface MyConnection extends Connection{
}
这样MyConnection.getClass().getInterfaces()得到是com.mysql.jdbc.Connection,所以下面代码将不会导致转换错误
Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), MyConnection.getClass().getInterfaces(), hander);
- 解决Proxy.newProxyInstance创建动态代理导致类型转换错误的问题
- Proxy.newProxyInstance动态代理[z]
- 动态代理之Proxy.newProxyInstance()
- 代理模式 Proxy.newProxyInstance
- java 代理Proxy.newProxyInstance
- 代理Proxy.newproxyinstance
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...今天
- JDK的动态实现代码-->Proxy.newProxyInstance()
- JAVA动态代理之java.lang.reflect.Proxy.newProxyInstance源码
- 【动态代理】使用构造方法创建代理类、使用 newProxyInstance.newProxyInstance()创建代理类
- 从代理模式再出发!Proxy.newProxyInstance的秘密
- Git 修改 proxy,解决代理导致的代码无法 push 或 pull 的问题
- Proxy.newProxyInstance()
- 类型转换导致的问题
- weblogic通过代理插件weblogic.servlet.proxy.HttpProxyServlet跨域访问导致session丢失问题的解决
- weblogic通过代理插件weblogic.servlet.proxy.HttpProxyServlet跨域访问导致session丢失问题的解决
- linux中安装navicat_for_mysql
- WaveOut播放音频
- C# 常用控件整理
- Arduino RF decoder
- VC 读取EXCEL表格
- 解决Proxy.newProxyInstance创建动态代理导致类型转换错误的问题
- Keil C51对C语言的关键词扩展
- 【PAT1025】PAT Ranking
- fedora配置国内yum更新源/以配置163开源镜像为例
- HDU 整数对
- 指针函数与函数指针的区别
- vim使用clang_complete插件简直太爽了
- C#中ToString格式
- 2013.11.28