动态代理模式分析--基于马士兵视频例子
代码改天上传。现在上传不上来、、
关于模式之外的代码准备:动态编译
Java作为动态语言的特点,这里要做的就是,通过代码来把一个存有java代码的简单的小程序写入到一个java文件中,然后调用java的CompilationTask对其进行编译并实例化,接下来自然就是调用运行了。
大体流程:
1.组织字符串,也就是要生成的java问的代码
2.写入到文件中去,名字暂时定为:ProxyStart.java ,package为learn
3.获取jdk编译器
4.拿到编译任务,进行编译
5.找到编译之后的类,加载这个class类文件到内存
6.通过反射对这个类实例化。并调用》
代码:test1.java
新的知识点:
可以看到,这个字符串将会是生成的代理类,有一个Moveable参数的构造方法,将要测试的Moveable实现类(这里是tank类)的实例对象传到代理类中,代理类中为m,由于代理类也实现了Moveable方法,我们可以通过实例化代理类来调用Move()方法,也是因为这样,我们在代理类的Move()方法中调用m.move(),这就相当于间接调用了tank的move方法,我们在m.move()前后添加计算运行时间的代码,就可以对这个tank运行时间的测试,若是要测试其他所有实现了Moveable接口的类的运行时间,只需要在对代理类实例化时调用的构造方法中传递个实例进去就行了。代码为
Tank类的测试
在代理类中,添加一个参数,这个参数就是中间部分接口(这里的理由说起来很绕,具体看代码。我们先假设现在的动态代理类是ProxyProcedure,我们用它生成的代理类名为TankTimeProxy,中间部分接口为HandlerProxy;因为我们要在生成的代理类TankTimeProxy中实现的接口move方法里面调用doAround方法,所以要实例化一个中间类,即HandlerProxy的实现类,HandlerProxy h = null,我们这里打算要通过构造方法来引入HandlerProxy的实现类,而我们这个TankTimeProxy的实例化是通过下边的动态编译来进行的,下边动态编译的代码部分就要传入TankTimeProxy需要的接口,也就是HandlerProxy,我们这时候传入的doProxy(Class inter, ProxyHandler h)的h就是用在这里:
Constructor ctr = c.getConstructor(h.getClass().getInterfaces());
Object m = (Object) ctr.newInstance(h);
Return m)