当前位置: 代码迷 >> J2SE >> 动态代理的内部实现。例子:数据库连接。该如何处理
  详细解决方案

动态代理的内部实现。例子:数据库连接。该如何处理

热度:232   发布时间:2016-04-24 01:34:26.0
动态代理的内部实现。例子:数据库连接。
Java code
/** * 单例模式,通过DBPool连接池获取数据库连接 * @author shi */public class JdbcUtils {        private static Logger logger = Logger.getLogger(JdbcUtils.class);        //简单的数据库连接池    private static DataSource dataSource = new DBPool();    private static JdbcUtils instance;         //构造函数私有化,为实现单例    private JdbcUtils() {    }        //注意:"锁"的方式,以及第二次"null"的判断(仔细思考:若两个线程同时到达)    public static JdbcUtils getInstance() {        if(instance == null) {            synchronized (JdbcUtils.class) {                if(instance == null) {                    instance = new JdbcUtils();                    }            }        }        logger.info("成功获取JdbcUtils实例");        return instance;    }        //返回连接Connection    public Connection getConnetion() throws SQLException {        return dataSource.getConnection();        }        //释放资源    public void free(ResultSet rs, Statement st, Connection conn) {        try {            if(rs != null) rs.close();        } catch (SQLException e) {            throw new JdbcException(e.getMessage());        } finally {            try {                if(st != null)st.close();            } catch (SQLException e) {                throw new JdbcException(e.getMessage());            } finally {                try {                    if(conn != null) conn.close();                } catch (SQLException e) {                    throw new JdbcException(e.getMessage());                }            }        }    }    }----------------------------------------/** * 数据库连接池 * @author shi */public class DBPool{    private static Logger logger = Logger.getLogger(DBPool.class);    private static LinkedList<Connection> connectionPool;    private static int currentCount;    private        Selec


上面是利用动态代理的一个小例子。但“动态代理”的内部机制是怎样实现的呢?还是通过“反射”吗?请大家指点。

------解决方案--------------------
Java code
我做了个测试 调用ProxyGenerator.generateProxyClass(proxyName, interfaces);方法得到字节码 写到文件中(.class文件) 然后通过JD反编译 得到代理类(.java文件)这个类是这样的public final class MyProxyClass extends Proxy implements MyInterface有一个构造方法public MyProxyClass(InvocationHandler paramInvocationHandler)    throws {    super(paramInvocationHandler);  }所以我们通常用动态代理是这么用的:写一个类,比如名字叫MyHandler,实现InvocationHandler接口.然后把MyHandler对象作为参数传给Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);这个方法.这个方法会调用ProxyGenerator.generateProxyClass(proxyName, interfaces);方法生成一个代理类.然后通过反射调用上面那个构造方法进行实例化,参数就是自己写的MyHandler的对象.而这个代理类的任何方法实际上都是调用这个MyHandler的invoke方法,只是不同方法的参数不同.所以无论你调用什么方法,实际上都在调用你写的invoke方法.这样你就可以在invoke方法里自由发挥,前插后插,随便你怎么插,这就是AOP.
------解决方案--------------------
探讨
引用:
谁说的动态代理就是反射啊?


我说肯定用到了反射 没说只用了反射

动态代理的本质就在这个方法里
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                    proxyName, interfaces);
这个proxyName难道不是反射得到的吗?

然后通过这个名字和接口生成java源代码 编译成字节码文件 调入虚拟机 实例化 返回对象

就这么简单
  相关解决方案