继续探索动态代理

        在昨天的Post中,三言两语把动态代理(Dynamic Proxy)大致介绍了一下并给出了一个例子,我想大家应该和我一样对Dynamic Proxy有一定认识了吧。然而Dynamic Proxy这个宝藏的底蕴是深厚的,三言两语又怎能发掘到精华呢?于是,偶带着很多疑问,对Dynamic Proxy来一次更全面的探索。
        在Dynamic Proxy中,最有意思的应该是Proxy创建的过程了。我们可以通过调用Proxy.newProxyInstance这个方法来创建一个Proxy的实例,然而这个Proxy的实例却可以被Cast成所绑定的interface的型别。为什么Proxy的实例可以成功地被Cast呢?在没有去考究之前,先让偶天马行空一番。Proxy中包含了一个特别的Inner Class,它的定义是这样的 public Class InProxy implements *。 而这个星号在Proxy创建的时候被具体的interface list所替代,这样InProxy的定义才完整,才能够基于这样的定义创建InProxy的实例。这跟Python中动态创建Class的模板有着几分相似啊!天马行空完了,不管对不对,玩玩想象力倒也不错。为了找到正确的答案,我于是打开Proxy这个Class的source code看个究竟。   

        从代码中,我们可以发现newProxyInstance方法等价于三个方法的调用:
None.gif    newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)  
None.gif
== Class proxyClass =
 Proxy.getProxyClass(loader, interfaces);
    Constructor cons 
= proxyClass.getConstructor(new Class[] { InvocationHandler.class }
);
    cons.newInstance(
new Object[] { h }
);
None.gif

在三个方法调用中,后面两个是类Class中十分常见的方法,并没有什么特别的,关注的重点落在了getProxy方法。在getProxy方法中,第一步是检查参数interfaces的是否invalid,如果这一组interface都是valid,将创建一个字符串以存储这些interface的名称。使用字符串而非Collection来存储interface的名称是出于性能以及弱引用(不是很明白这里为什么需要用到弱引用)的考虑;第二步是在一个WeakHashMap中以ClassLoader作为Key去查找另外一个Map,而这个Map则缓存着已经创建的Proxy Class,如果在这个Map中找到了需要的Proxy Class则返回,否则通过ProxyGenerator.generateProxyClass方法以及一个名为defineClass0的native方法创建Proxy Class,而这两个方法我都无从寻找它们的source code。Oh,my God!
        Anyway,这一阵瞎摸索还是让我知道了,Proxy Class之所以能够被Cast成所绑定的interface的型别,靠的就是这两个方法了。尽管没有办法到这两个方法的内部看个究竟多少让我有些失落,但是,这样把source code阅读了一番,倒给我提出了更多的问题。噢,又有好玩的东西可以去发掘了,so great!
       

转载于:https://www.cnblogs.com/perhaps/archive/2005/09/02/229114.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值