java反射机制之深入理解

为什么使用动态代理

在传统的静态代理设计模式里面,每个代理类只能为一个或者多个已经去确定的接口进行代理,在代理设计模式其实就是利用接口的多态性,由于实现的子类不一样,所以我们可以使得一个类成为代理类,让这个类可以实现真实类的一些业务。但是代理类和真实业务逻辑类都需要实现同一个接口,这就是静态代理设计的缺点,因为代理类受到了接口的限制。

动态代理设计模式

这个其实利用的是java里面的反射机制,通过反射机制我们可以知道一个真实类实现了什么借口?这个真实类的类加载器是哪个,在代理类调用方法的时候,我们实现一个InvocationHandle接口,该接口是代理实例 调用处理程序 的实现接口(调用处理的一个程序,或者一个方法,其实就是一个方法,invoke()执行方法)
下面讲解我们构建动态代理的三个主要的接口和类

Proxy

这个类是所创建的动态代理实例的所有父类
public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):该方法用于返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表(与真实主题类的接口列表一致),第三个参数h表示所指派的调用处理程序类。(这个类是实现了InvocationHandle接口的类,这个类要将真实类织入,当由这个Proxy产生的代理实例发生方法额调用的时候,它会将调用交给到这个调用程序处理类,让他来对调研进行处理)

InvocationHandle

InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:
public Object invoke(Objectproxy, Method method, Object[] args):该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。

动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时,调用请求会将请求自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。