一、JDK动态代理是什么
利用代理可以在运行时创建一个实现了一组给定接口的新类,它具有下列方法: 指定接口所需要的全部方法,Object类中的全部方法。
二、InvocationHandler接口
调用处理器是实现了 java.lang.reflect.InvocationHandler接口的类(中介类)对象
InvocationHandler 接口只有一个方法:
Object invoke(Object proxy, Method method, Object[]args)throws Throwable
定义了代理对象调用方法时希望执行的动作。 其中,proxy:代表动态代理对象 method:指代的是我们所要调用真实对象的某个方法的Method对象 args:指代的是调用真实对象某个方法时接受的参数
在代理真实对象前/后,我们可以添加一些自己的操作。
调用真实对象的方法:method.invoke(target,args);真实对象target作为中介类的成员变量。
当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用,并向其传递 Method 对象和原始的调用参数。
三、创建代理对象
创建代理对象 :使用 java.lang.reflect.Proxy 类的newProxylnstance方法
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws IllegalArgumentException 构造实现指定接口的代理类的一个新实例。
loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载, 用 null 表示使用默认的类加载器。
interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该组接口(多态),这样我就能调用这组接口中的方法了
handler:一个调用处理器,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
代理对象所调用的所有方法会调用给定处理器对象的invoke方法。
四、代理类的特性
①代理类是在程序运行过程中创建的,然而,一旦被创建,就变成了常规类,与虚拟机中的任何其他类没有什么区别。
②所有的代理类都扩展于 Proxy类。一个代理类只有一个实例域— —调用处理器,它定义 在 Proxy 的超类中。 为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。
③所有的代理类都覆盖了 Object 类中的方法 toString、equals 和 hashCode。如同所有的代理方法一样,这些方法仅仅调用了调用处理器的invoke。Object 类中的其他方法(如 clone 和 getClass) 没有被重新定义。
④没有定义代理类的名字,Sun 虚拟机中的 Proxy类将生成一个以字符串 $Proxy开头+数字的类名。
⑤对于特定的类加载器和预设的一组接口来说,只能有一个代理类。也就是说,如果使用 同一个类加载器和接口数组调用两次 newProxylustance方法的话, 那么只能够得到同一个类 的两个对象,也可以利用 getProxyClass方法获得这个类:
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) 返回实现指定接口的代理类。
⑥代理类一定是 public 和 final。如果代理类实现的所有接口都是 public,代理类就不属于某个特定的包;否则,所有非公有的接口都必须属于同一个包,同时,代理类也属于这个包。
⑦可以通过调用 Proxy 类中的 isProxyClass方法检测一个特定的 Class 对象是否代表一个代理类。
static boolean isProxyClass(Class<?> cl) 如果 cl 是一个代理类则返回 true。
五、使用动态代理的过程
①至少一个接口(被代理的接口)
②一个实现了这些接口的类(委托类,真实对象)
③一个实现了InvocationHandler接口的类(中介类,需要一个委托类的对象)
④Proxy.newProxylnstance()方法创建代理对象
⑤通过代理类对象调用真实对象的方法