Java动态代理语法Proxy类原理详解
1、前言
写动态代理的代码涉及了一个非常重要的类Proxy,通过Proxy的静态方法newProxyInstance才会动态创建代理对象。
2、newProxyInstance方法
publicstaticObjectnewProxyInstance(ClassLoaderloader,Class>[]interfaces,InvocationHandlerh)
三个参数分别表示:loader表示类加载器,interfaces表示代码要用来代理的接口,h表示一个InvocationHandler对象,前面两个参数容易理解,
最后一个InvocationHandler是什么?
InvocationHandler是一个接口,官方文档解释说,每个代理的实例都有一个与之关联的InvocationHandler实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的InvocationHandler实现类,由它决定处理。
publicinterfaceInvocationHandler{ publicObjectinvoke(Objectproxy,Methodmethod,Object[]args) throwsThrowable; }
InvocationHandler内部只有一个invoke()方法,正是这个方法决定了怎么样处理代理传递过来的方法调用。其中参数proxy表示代理对象,method表示代理对象调用的方法,args表示调用的方法中的参数。所以Proxy动态产生的代理会调用InvocationHandler实现类,所以InvocationHandler才是实际执行者。
3、代码实例
//抽象主题 interfaceAbstractSubject { voidrequest(); } //真实主题 classRealSubjectimplementsAbstractSubject { publicvoidrequest() { System.out.println("访问真实主题方法..."); } } //真实主题 classRealSubject1implementsAbstractSubject { publicvoidrequest() { System.out.println("访问真实主题方法1..."); } } //动态代理类 classDynamicProxyimplementsInvocationHandler{ privateObjectobject; publicDynamicProxy(Objectobject){ this.object=object; } @Override publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ before(); Objectresult=method.invoke(object,args); after(); returnresult; } privatevoidbefore(){ System.out.println("hello!"); } privatevoidafter(){ System.out.println("bye!"); } } //测试类 publicclassTestDynamicProxyPattern{ publicstaticvoidmain(String[]args){ AbstractSubjectabstractSubject=newRealSubject(); DynamicProxydynamicProxy=newDynamicProxy(abstractSubject); Proxy.newProxyInstance(abstractSubject.getClass().getClassLoader(),abstractSubject.getClass().getInterfaces(),dynamicProxy); abstractProxy.request(); } }
上述动态代理只需要传入需要被代理类的对象(DynamicProxydynamicProxy=newDynamicProxy(abstractSubject)),然后调用Proxy类的工厂方法newProxyInstance去动态地创建一个代理类,最后调用代理类的方法便实现了“增强功能”。使用了动态代理之后,无论有多少类多少方法需要增加逻辑,只需要在使用的时候将类对象传入得到代理对象,然后使用代理对象调用需要增强的方法即可。
所以这时候如果增加一个实现抽象主题的真是主题类,比如说叫做RealSubject1,这个时候只要只要把该类的对象传入动态代理类DynamicProxy中,通过接口又可以实现接口AbstractSubject的实现类。
这样来实现:
AbstractSubjectabstractSubject1=newRealSubject1();
DynamicProxydynamicProxy=newDynamicProxy(abstractSubject1);
4、总结
1、区别于静态代理的生成代理类,动态代理的代理类通过Proxy.newInstance()方法生成。静态代理和动态代理的区别是在于要不要开发者自己定义Proxy类。
2、不管是静态代理还是动态代理,代理与被代理者都要实现接口,还是要是面向接口编程,目的都是增强现有功能。
3、动态代理通过Proxy动态生成proxyclass,但是它也指定了一个InvocationHandler的实现类。
4、动态代理也有缺陷,它要求需要代理的对象必须实现了某个接口,而且也不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。