现在的位置: 首页 > 综合 > 正文

学习动态代理的总结

2013年01月24日 ⁄ 综合 ⁄ 共 2139字 ⁄ 字号 评论关闭

这两天好好研究了动态代理,把一些体会写出来,以备后用

代理分为静态代理和动态代理

静态代理需要手动为每个代理类的每个方法添加要实现的功能(如日志)

而动态代理则为需要添加功能的类自动生成代理类,其实jdk proxy已经为我们提供了方法

静态代理就是面向对象中的代理模式,使用面向对象的方式实现代理对象,这个代理对象的类是自己手工编写的。

动态代理是编程语言根据代理规则自动生成代理类,并产生代理对象。常用的动态代理有 JDK Proxy 和 cglib。

JDK Proxy 是在运行时产生代理类的字节码,再由类加载器加载这些字节码然后创建代理对象。
Cglib 是使用一种叫做 ASM 的字节码工具,由程序的方式产生字节码。

迷惑的地方时invoke方法是何时被执行的

我们在InvocationHandler实现类中写一个newInstance(),用来产生代理类,返回一个object类型的  new Proxy.newProxyInstance(loader, interfaces, h)的代理类

里面有三个参数,第一个是用来将目标对象(即真实类)加载到JVM上,第二个是实现目标对象接口的所有方法,有意思的是第三个方法,当我们调用目标对象的方法时,就会转到第三个参数,它指的是代理类对象,讲调用第三个方法时,它会自动调用invoke方法

在invoke(Object proxy, Method method, Object[] args)方法中,

Object proxy          -----代理类对象

Method method         -----被代理对象的方法(这里不是接口的抽象方法了,是具体的实现类中的方法)

Object[] args         -----该方法的参数数组

在方法里面可以加入需要添加的如日志,安全性检查功能

方法里面需要实现的就一句,method.invoke(target,args);

即目标对象,参数,它的作用就是执行目标对象里面的方法

参考了下面的讲解

1.     Proxy即动态代理类;

2.     Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用;

它有三个参数:

ClassLoader loader    ----指定被代理对象的类加载器

Class[] Interfaces    ----指定被代理对象所以事项的接口

InvocationHandler h  ----指定需要调用的InvocationHandler对象

3.     实现InVocationHandler接口的LogHandler_old对象

这个对象的invoke()方法就是Proxy这个动态代理类所代理的接口类的抽象方法的真实实现;

它有三个参数:

Object proxy          -----代理类对象

Method method         -----被代理对象的方法(这里不是接口的抽象方法了,是具体的实现类中的方法)

Object[] args         -----该方法的参数数组

 

JDK中具体的动态代理类是怎么产生的呢?

1.产生代理类$Proxy0

执行了Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

将产生$Proxy0类,它继承Proxy对象,并根据第二个参数,实现了被代理类的所有接口,自然就可以生成接口要实现的所有方法了(这时候会重写hashcodetoStringequals三个方法),但是还没有具体的实现体;

2.    将代理类$Proxy0类加载到JVM

这时候是根据Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第一个参数----就是被代理类的类加载器,把当前的代理类加载到JVM

3.    创建代理类$Proxy0类的对象

调用的$Proxy0类的$Proxy0InvocationHandler)构造函数,生成$Proxy0类的对象

参数就是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第三个参数

这个参数就是我们自己实现的InvocationHandler对象,我们知道InvocationHandler对象中组合加入了代理类代理的接口类的实现类;所以,$Proxy0对象调用所有要实现的接口的方法,都会调用InvocationHandler对象的invoke()方法实现;

4.    生成代理类的class byte

动态代理生成的都是二进制class字节码

-----------------------------自己的理解,不足之处,恳请指点---------------------------------------------------

抱歉!评论已关闭.