版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、java的动态代理机制详解-编程开发技术java的动态代理机制详解原文出处:xiaoluo501395377在学习spring的时候,我们知道spring主要有两大思想,一个是ioc,另一个 就是a0p,对于ioc,依赖注入就不用多说了,而对于spring的核心a0p来说, 我们不但要知道怎么通过a0p来满足的我们的功能,我们更需要学习的是其底层 是怎么样的一个原理,而a0p的原理就是java的动态代理机制,所以本篇随笔 就是对java的动态机制进行一个回顾。在java的动态代理机制中,有两个重要的类或接口,一个是 invocationhandlcr (interface) > 另一个则
2、是 proxy (class),这一个类和接口 是实现我们动态代理所必须用到的。首先我们先来看看java的api帮助文档是 怎么样对这两个类进行描述的:invocat ionhandler:invocationhandler is the interface implemented by the invocation handler of a proxy instance each proxy instance has an associated invocation handle匚 when a method is invoked on a proxy instance, the metho
3、d invocation is encoded and dispatched to the invoke method of 让s invocation handler.每一个动态代理类都必须耍实现invocationhandler这个接口,并冃每个代理类 的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这 个方法的调用就会被转发为由invocationhandlcr这个接口的invoke方法来 进行调用。我们来看看invocationhandler这个接口的唯个方法?invoke?方法:object invoke(object proxy, method metho
4、d, object args) throws throwable我们看到这个方法一共接受三个参数,那么这三个参数分别代表什么呢?object invoke(object proxy, method method, object args) throws throwableproxy:指代我们所代理的那个真实对象method:指代的是我们所要调用真实对象的某个方法的method对象args:指代的是调用真实对象某个方法时接受的参数如果不是很明白,等下通过一个实例会对这几个参数进行更深的讲解。接卜来我们来看看proxy这个类:proxy provides static methods for cr
5、eating dynamic proxy classes and instances, and it is al so the superclass of al 1 dynamic proxy classes created by those methods.proxy这个类的作用就是用來动态创建一个代理对象的类,它提供了许多的方 法,但是我们用的最多的就是?newproxyinstance?这个方法:public static object newproxylnstance(classloader loader, class<?> interfaces,invocationhan
6、dler h) throws illegalargumentexceptionreturns an instance of a proxy class for the specified interfaces that dispatchcs method invocations to the specified invocation handler这个方法的作用就是得到一个动态的代理对彖,其接收三个参数,我们来看看这 三个参数所代表的含义:public static object newproxytnstance(classloader loader, class<?> intcr
7、faccs, invocationllqndler h) throws illcgalargumcntexccptionloader:一个classloader对彖,定义了由哪个classloader对彖来对主成的代理对象进行加载interfaces:一个interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称 实现了该接口(多态),这样我就能调用这组接口屮的方法了h:一个invocationhandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个invocationhandler对象上好了,在介绍
8、完这两个接口(类)以后,我们来通过一个实例来看看我们的动态代 理模式是什么样的:首先我们定义了一个subject类型的接口,为其声明了两个方法:public interface subjectpublic void rent();public void hello(string str);接着,定义了一个类来实现这个接口,这个类就是我们的真实对彖,realsubject 类:publ ic class realsubject imp!ernents subject©overridepublic void rent()system, out. println(i want to ren
9、t my house");©overridepublic void hello(string str)system. out. println("hello: " + str);下一步,我们就要定义一个动态代理类了,前面说个,每一个动态代理类都必须 要实现invocationhandler这个接口,因此我们这个动态代理类也不例外:publ ic class dynami eproxy implements invocationheindler/这个就是我们要代理的真实对彖private object subject;/构造方法,给我们要代理的真实对象赋初
10、值public dynami eproxy(object subject)this. subject 二 subject;©overridepublic object invokc(0bjcct objeet, method method, object args) throws throwable/ 在代理真实对象前我们可以添加一些自己的操作system. out println("before rent house");system. out. println("method: + method);/当代理对象调用真实对象的方法吋,其会自动的跳转到代
11、理对象关联的handler对象的invoke方法來进行调用method. invokc(subject, args);/在代理真实对彖后我们也可以添加一些自己的操作system, out. printin (,zaf ter rent house");return nul1 ;最后,来看看我们的cl ient类:public class clientpublic static void main(string args)/我们要代理的真实对象subject real subject 二 new real subject();/我们要代理哪个真实对象,就将该对彖传进去,最后是通过该真实
12、对彖来调用其方法的invocationhandler handler 二 new dynamicproxy(realsubject);/*通过proxy的newproxyinstance方法来创建我们的代理对象,我们 来看看其三个参数* 第一个参数 handler. getclass (). getclassloader (),我们这里使 用handler这个类的classloader对象来加载我们的代理对象* 第二个参数 realsubject. getclass (). gettnterfaces (),我们这里 为代理对象提供的接i i是真实对象所实行的接i i,表示我要代理的是该真实对
13、 彖,这样我就能调用这组接口屮的方法了*笫三个参数handler,我们这里将这个代理对彖关联到了上方的 invocationhandler 这个对象上*/subject subject =(subject)proxy.newproxyinstance(handler getclass() getclassloader(), realsubject getclass (). getlnterfaces (), handler);system. out printin(subject getclass() gctnamc (); subject. rent ();subject, hello(&q
14、uot;world"); 我们先來看看控制台的输出:$proxyo before rent housemethod:pub1ic abstract void com.xiaoluo. dynamicproxy. subject. rent() i want to rent my houseafter rent house before rent housemethod:pub1ic abstract voidcom. xiaoluo. dynomieproxy. subject, hello(java. lang. string)hello: worldafter rent hous
15、e我们首先来看看?$proxyo这东西,我们看到,这个东西是由?system. out. printin (subject. getclass (). getname ();这条语句打印出来 的,那么为什么我们返回的这个代理对彖的类名是这样的呢?subject subject =(subject)proxy.newproxyinstance (handler. getclass(). getclassloader(), realsubject.getclass (). gettnterfaces (), handler);可能我以为返回的这个代理对象会是subject类型的对象,或者是 inv
16、ocationhandler的对象,结杲却不是,首先我们解释一下为什么我们这里可 以将其转化为subject类型的对象?原因就是在newproxylnstance这个方法的 笫二个参数上,我们给这个代理对象提供了一组什么接口,那么我这个代理对象 就会实现了这组接口,这个吋候我们当然可以将这个代理对象强制类型转化为这 组接口中的任意一个,因为这里的接口是subject类型,所以就可以将其转化为 subject 类型了。同时我们一定要记住,通过?proxy. newproxylnstance创建的代理对象是在jvm 运行时动态生成的一个对象,它并不是我们的invocationhandler类型,也
17、不 是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,接着我们來看看这两句subject. rent ();subject, hello("world");这里是通过代理对象来调用实现的那种接口中的方法,这个吋候程序就会跳转到 由这个代理对象关联到的handler中的invoke方法去执行,而我们的这个 handler对彖又接受了一个realsubject类型的参数,表示我要代理的就是这 个真实对象,所以此时就会调用handler中的invoke方法去执行:public object invoke(object
18、 object, method method, object args) throws throwable/在代理真实对象前我们可以添加一些自己的操作system .out.prin tin ("'before rent house");system, out. printin (,zmethod:z,+ method);/ 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象 关联的handler对象的invoke方法來进行调用method invoke (subject, args);/在代理真实对象后我们也可以添加一些自己的操作system, out. printin(after rent house");return null;我们看到,在真正通过代理对象来调用真实对象的方法的吋候,我们可以在该方 法前后添加自c的一些操作,同时我们看到我们的这个method对象是这样的:public abstract void comxiaoluo. dynamieproxy. subjectrent ()p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论