借鉴:java
https://blog.csdn.net/yangaiyu/article/details/73827043session
若本身实现代码加强,则须要为每一个目标对象单独编写一个代理Class对象而后用类加载器加载,实例化,再调用,这样每一个目标对象都得单独地编写代理Class对象以达到目的(即静态代理)。数据结构
为了减小代理类地编写,咱们类的消息通常都由Class对象在JVM方法区中被加载(反射和new都是),若想不编写代理class还要有目标类的信息,天然而然地能够想到接口,若能对接口进行动态代理,则可将实现该接口并调用该接口中的方法(可能不止实现一个接口)的目标类归为以类进行代码编写(这就是为何要使用动态代理的缘由),可是,接口并不能实例化jvm
但java.lang.reflect.Proxy类有个getProxyLoader(ClassLoader,interfaces)方法,只要你给他传入类加载器和一组接口,它就能给你返回代理Class对象。(意味着它变成了一个对象,能够带有构造器进行实例化)函数
InvocationHandler handler = new DynamicProxy(realSubject); Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代咱们所代理的那个真实对象 method: 指代的是咱们所要调用真实对象的某个方法的Method对象 args: 指代的是调用真实对象某个方法时接受的参数
可能会觉得返回的这个代理对象会是Calculator类型的对象,或者是InvocationHandler的对象,结果却不是,首先咱们解释一下为何咱们这里能够将其转化为Subject类型的对象?缘由就是在getPorxyClass这个方法的第二个参数上,咱们给这个代理对象提供了一组什么接口,那么我这个代理对象就会实现了这组接口,这个时候咱们固然能够将这个代理对象强制类型转化为这组接口中的任意一个,由于这里的接口是Subject类型,因此就能够将其转化为Subject类型了。.net
同时咱们必定要记住,以上获取代理Class、获得有参构造函数、实例化后建立的代理对象是在jvm运行时动态生成的一个对象,它并非咱们的InvocationHandler类型,也不是咱们定义的那组接口的类型,而是在运行是动态生成的一个对象,而且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。设计
* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader:一个ClassLoader对象,定义了由哪一个ClassLoader对象来对生成的代理对象进行加载 interfaces:一个Interface对象的数组,表示的是我将要给我须要代理的对象提供一组什么接口,若是我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪个InvocationHandler对象上