JAVA动态代理

JAVA动态代理

借鉴:java

https://www.zhihu.com/question/20794107/answer/658139129?utm_source=wechat_session&utm_medium=social&utm_oi=911918804941021184&utm_content=sec数组

https://blog.csdn.net/yangaiyu/article/details/73827043session

  • 若本身实现代码加强,则须要为每一个目标对象单独编写一个代理Class对象而后用类加载器加载,实例化,再调用,这样每一个目标对象都得单独地编写代理Class对象以达到目的(即静态代理)。数据结构

  • 为了减小代理类地编写,咱们类的消息通常都由Class对象在JVM方法区中被加载(反射和new都是),若想不编写代理class还要有目标类的信息,天然而然地能够想到接口,若能对接口进行动态代理,则可将实现该接口并调用该接口中的方法(可能不止实现一个接口)的目标类归为以类进行代码编写(这就是为何要使用动态代理的缘由),可是,接口并不能实例化jvm

  • 但java.lang.reflect.Proxy类有个getProxyLoader(ClassLoader,interfaces)方法,只要你给他传入类加载器和一组接口,它就能给你返回代理Class对象。(意味着它变成了一个对象,能够带有构造器进行实例化)函数

  • 有了代理Class对象(代理Class对象为代理类->数据结构,代理对象为实例化的对象),咱们能够经过该对象获得有参的构造器(基于InvocationHandle接口),咱们就能够反射建立实例了,而基于上述接口的构造器能够基于实例化的InvocationHandle接口的对象实例化,使得代理对象经过handler对象中的invoke方法去加强目标对象(InvocationHandle接口是一个规范,代理对象中会有成员变量去接收它,并为他的proxy、method、args等传参,为了便于设计把他提取出来
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为中,最后一个数字表示对象的标号。设计

  • 上面的并无传入目标对象,须要在invoke里新建相应的对象,咱们经常使用的是传入相应的目标对象,而将上面的封装为一个函数,以适用于更多的对象调用,而更经常使用的是Proxy.newProxyInstance()方法,直接将上述流程都封装了。
* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

loader:一个ClassLoader对象,定义了由哪一个ClassLoader对象来对生成的代理对象进行加载

interfaces:一个Interface对象的数组,表示的是我将要给我须要代理的对象提供一组什么接口,若是我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了

h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪个InvocationHandler对象上

  • 以后在invoke中调用method.invoke时,即为代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用(反射实现),能够深刻getPorxyClass与创造构造器的三个步骤或newProxyInstance中查看相关实现。
  • 以上即是动态代理的所有流程了

相关文章
相关标签/搜索