jdk的动态代理要求根据相应的接口而生成实例作为目标对象的代理的,当调用代理对象
的每一个方法时,都会执行InvocationHandler实例中的invoke()方法。那就是说,在
构建代理对象的时候,在代理对象中植入了一个InvocationHandler引用,构造时把实
例传入就是了,这个过程是在Proxy.newProxyInstance(loader, interfaces, h)中
进行的,这是第三个参数。当然还要获得目标(target)所实现的接口信息对象,由第
二个参数传入。在实现接口的方法时,对调用第一个参数对象的invoke()方法,因为代
理对象与目标对象实现的是同一个接口,所以利用公共接口的引用调用方法的时候,就
会给人感觉像调用目标对象的方法的感觉。实际上是用公共接口的引用调用了代理对象
的方法,而代理对象的方法也会去调用内置对象(InvocationHandler接口的实例)的
方法,而该方法又会调用目标对象的原方法。所以我们在构建invoke()方法时,可以加
入更多的实现,以达到动态植入方法的效果。invoke()方法中的Method对象与
Proxy.newProxyInstance(loader, interfaces, h)中的interfaces中的方法相对应,
所以Method对象中的invoke()方法的第一个参数对象(target),必须实现以
上interface.也就是说,这个公共的interface是两者关系的关键。还有就是,要注意
接口方法的参数问题。Method.invoke(Object target,Object[] args)中的数组,代
表参数的个数,该函数内部会判断参数的个数,所以调用时,直接调用为
invoke(target,args)就可以了,对于无参函数也可以这样调用。
java.lang.reflect.Proxy是所有生成的代理类的超类,其生成料理类的原理是通过
sun.misc.ProxyGenerator的generateProxyClass(proxyName, interfaces)
方法生成代理类的字节码数组,然后真调用defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length)方法来生成代理类。再吧该类放回到
缓冲理的WeakHashMap里面。