jdk动态代理使用_第1页
jdk动态代理使用_第2页
jdk动态代理使用_第3页
jdk动态代理使用_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、最近做项目用到了动态代理,感觉还不熟悉, 于是从网上下了尚学堂的相关视频,花了一个下午终于搞明白了动态代理,动态代理使用很简单,原理也不难,现在把使用方法记下来,以备用。首先要明白的是,要代理一个类必须要有一个接口,就是被代理类必须实现了某个接口所以我们先写一个接口:package xy.test; /*说话的接口,对某个人说话,并且要有返回值*authordemo*/publicinterface speak public string speak(string tosomebody); 然后再写people类,他实现了speak接口:package xy.tes

2、t; import java.util.random; /*people类, 实现 speak 接口*authordemo*/publicclass people implements speak overridepublic string speak(string tosomebody) system.out .println(hello +tosomebody); try thread.currentthread().sleep( newrandom().nextint(10000);/随机休眠 10 秒以内的时间 catch (interruptedexception e) e.prin

3、tstacktrace(); returnreturn str is: hello +tosomebody; 那么, 现在我们需要算出来这个人说话用了多长时间,也就是在调用people1的 speak()方法前后各进行一些处理,在不改变源代码的情况下,有什么办法呢?1、 继承:再写一个类,people2,继承与people,并且重写speak()方法,那么我们就可以在调用 people1 的 speak 方法前后做任何感兴趣的逻辑。2、 聚合:新写一个类people1timeproxy, 他也实现speak接口,但是这个类拥有一个people的对象,在实现speak 接口的 speak()方法

4、中, people3 直接调用people1 的逻辑,这样也可以在people1 的 speak()方法前后执行想要的逻辑。以上的两种方式都不太好,第一种方式是大家最容易想到的方式,但是非常不灵活,一般不推荐使用。第二种方式灵活性要高于第一种,可以理解为静态代理,但是也还不够灵活,比如说现在我想在让这个人也实现走路的接口,算出他走路的时间,那么我们是不是还得写一个people1walkproxy 也就是静态代理是依赖于接口的,有多少个接口就需要多少个代理,显然也是非常灵活。好,下面开始介绍动态代理,动态代理就是可以不管有多少个接口,我只要一个代理类就可以了,要使用动态代理,我们需要实现一个接口

5、,叫做invocationhandler, 实现方法invoke。 实现这个接口的目的就是让jdk 知道我想在某个方法(这里是 speak()方法 )前后加入什么逻辑,可以这么写package xy.test; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; /*代理逻辑*authordemo*/publicclass peopletimehandler implements invocationhandler private object target; /需要代理的目标p

6、ublic peopletimehandler() /默认构造方法super(); public peopletimehandler(object target) /有参数的构造方法super(); this. target = target; public object gettarget() /returntarget; publicvoid settarget(object target) /target 的getter and setterthis. target = target; overridepublic object invoke(object proxy, method m

7、ethod, object args)/invocationhandler的方法,定义我们需要在代理对象的方法前执行什么逻辑throws throwable system.out.println(“proxy name is :”proxy.getclass().getname();long start=system.currenttimemillis(); system.out .println(-start to speak -); /得到起始时间object obj=method.invoke(target, args);/这是利用反射机制,调用target对象的 method方法, a

8、rgs 是该方法需要传入的参数,obj是这个方法的返回值system.out .println(-end to speak -); /得到结束时间long end=system.currenttimemillis(); system.out .println( this people speak cost time +(end-start)+ms ); return obj; 现在被代理的对象有了,代理的逻辑也有了,我们只需要一个代理对象,用一个client类测试一下:package xy.test; import java.lang.reflect.proxy; publicc

9、lass testclient publicstaticvoid main(string args) peopletimehandler handler = new peopletimehandler(newpeople();/代理类/得到代理对象, 第一个参数是指定classloader,第二个参数指定被代理的类的接口,是一个 class数组,第三个参数是代理类speak sp = (speak) proxy.newproxyinstance( speak.class.getclassloader(),new class speak.class ,handler); string str =

10、 sp.speak( wupeng ); system.out .println(* + str); 组后打印出:proxy name is :$proxy0-start to speak - hello wupeng -end to speak - this people speak cost time 3953ms *return str is: hello wupeng 总结:使用动态代理很简单,但是我们需要弄清楚它的实现方式。我们在调用java.lang.reflect.proxy.newproxyinstance(classloader,interface,handler)方法的时候,其实是xy 为我们动态的生成了一个类,并且把这个类加载到内存,这个类叫做 $proxy0 ,最后把这个类的对象返回下面谈谈 $proxy0 这个类,它动态的实现了我们传入的接口interface,所以我们就可以把它强转为传入的任意接口interface,并且它的内部也有一个handler 接口的对象,而在实现这个接口的方法时,$proxy0 直接调用的handler的 inv

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论