1.
以上,完成了动态代理的生成。
但它是实现了Moveable接口的动态代理,
而我们想要的是实现任意接口的代理。

2.
因此,我们要修改的是,拼接sql语句的字符串:
建立Proxy.java
public static Object newProxyInstance throws Exception{
}

将刚才所写的测试方法全部拷贝至此方法当中,既然要实现多种接口的代理,那么参数中有必要写个接口的:
故改写为:
public static Object newProxyInstance(class infce) throws Exception{

}
动态拼接要代理的类:

将原来的语句("public class TankTimeProxy implements Moveable {" + rt + )修改为
//此处用infce.getName()来拿到要被代理的类的接口的名字
//注意:此处要用infce.getName(),因为如果只是用infce,则会调用它的toString方法,会在类前面自动加上interface
"public class TankTimeProxy2 implements " +infce.getName() + "{" + rt + 
运行,也许会出会错误,但是不要紧,我们这一步只是想完成代理对象的变化,只需关心它生成的java文件是否符合我们的希望就可以了。
看到生成的类是:public class TankTimeProxy implements com.compiler.test.Moveable
OK,成功。

这样呢,我们就完成了对于任意类的代理。

但是,我们将代理的方法move(),写死了。这是我们所不希望的,我们希望可以自动找到接口中的方法。

3.
先建立一个小测试文件好了:Test.java
public class Test2 {
///用反射,来知道 一个接口中有多少个方法
///站在classloader的角度,对象 中的方法也是对象
public static void main(String[] args) {
//import java.lang.reflect.Method;
Method[] methods = com.compiler.test.Moveable.class.getMethods();
for(Method m:methods){
System.out.println(m);    //打印结果:public abstract void com.compiler.test.Moveable.move()
System.out.println(m.getName());   //打印结果:move
}
}
}

也就是说,我们可以用上面的方式来获得接口中的方法。测试成功后,我们把它引入到我们的Proxy.java中:
//但要注意,不能再用 com.compiler.test.Moveable.class.getMethods(),因为我们要用任意的类,所以应改为infce.getMethods();
代码如下:

String rt = "\r\n";
///用于method的字符串
String methodStr = "";
Method[] methods = infce.getMethods();
for(Method m:methods){
methodStr  = methodStr + "@Override" + rt + 
"public void " + m.getName() + "(){" + rt +
"\t\tlong start = System.currentTimeMillis();" + rt +
"\t\tt." + m.getName()+ "();" + rt +
"\t\tlong end = System.currentTimeMillis();" + rt +
"\t\tSystem.out.println(\"time: \" + (end - start));" + rt +
"\t}";
}
System.out.println(infce);
String str = 
"package com.compiler.test;" + rt +
"public class TankTimeProxy2 implements " +infce.getName() + "{" + rt + 
"\tpublic TankTimeProxy2(Moveable t){" + rt + 
"\tsuper();" + rt +
"\tthis.t = t;" + rt +
"\t}" +  rt +
"\tMoveable t;" + rt +
//将这里替换
methodStr + 
"}";

这样呢,我们就完成了为每一个方法加上了一个时间代理。(注意,其中函数的返回值可以通过反映拿到。这里简写为都是void类型的)

另外,既然是实现了任意接口的代理,代码的结尾处:
Moveable m = (Moveable)ctr.newInstance(new Tank());  
m.move();
也要改为:
//用到了反射
生成一个类的对象,现在需要把它返回去。由于不知道是什么接口,所以用Object
Object o = (Object)ctr.newInstance(new Tank());   //传入参数,正式生成对象
return o;

测试:Client.java中:

public static void main(String[] args) throws Exception {
// Moveable m =(Moveable) Proxy.newProxyInstance(Moveable.class);
Moveable m =(Moveable) Proxy.newProxyInstance(Comparable.class);   //生成的文件会有编译错误,不过不要紧,我们只是看到生成的文件中,被代理的类和被重写的方法已经达到要求就可以了。
m.move();
}

好了,到目前为止,我们已经做到了:我们可以不同的类,并重写各种类中的方法了。
我们现在也可以做个小小的屏蔽:指定在其他地方生成.java文件和class文件,这样,在项目中就真正看到代理了文件了。
由于用途不大,我就没做这个的试验。

ok,又到了提出问题的时候了。现在的问题是:
这个newProxyInstance只是实现了时间代理,但我还想有日志代理,验证代理,……等等,那我该怎么办呢?且听下回分解。

学习动态代理stepbystep(3)相关推荐

  1. 学习动态代理stepbystep(4)

    通过上三篇文章,我想大家对"代理"这个概念有点明白了,但在(3)的代码中,还是有一个很大的问题,它并没有找到一个动态的实质. 我的意思是说,在Proxy.java中,对于计时的代码 ...

  2. 学习动态代理stepbystep(2)

    学完了静态的,进行一个小小的进阶了... 这篇文章,是对java动态代理的一个小小的模拟. 有一个假设:被代理的类已经实现了一个接口[我们采用聚合方式].(用继承也可以,但是不推荐) 模拟jdk的实现 ...

  3. Mybatis源码学习-动态代理

    Mybatis源码学习-动态代理 binding包下面是mybatis的mapper动态代理 // Mybatis官方手册建议通过mapper对象访问mybatis,因为使用mapper看起来更优雅 ...

  4. 学习动态代理前先看看-ASM

    关键词:ASM    字节码 在<学习动态代理前先看看-class字节码>中提到,我们是直接可以面向.class文件进行编码的,但是编写一个字节码内容是十分复杂的,好在有框架提供了功能.比 ...

  5. Spring——AOP学习(静态代理和动态代理模式)

    Spring--AOP学习(静态代理和动态代理模式) 一.代理模式 我们知道学习Spring最重要的两个知识点就是IOC和AOP,AOP的主要思想就是动态代理模式.在了解AOP之前我们必须学习动态代理 ...

  6. java动态代理_Java中的动态代理一

    方法newProxyInstance介绍 这篇开始学Java中的动态代理部分,刚开始,我们不去了解什么是动态代理相关的概念,除了动态代理,还有静态代理.我们学习动态代理直接从学习一个方法开始,这个方法 ...

  7. 十八、泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器基础加强

    l 泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器 泛型 1 回顾泛型类 泛型类:具有一个或多个泛型变量的类被称之为泛型类. public class A<T> { ...

  8. Spring动态代理原理是什么?

    动态代理的两种模式 jdk动态代理    //基于实现接口 Cglib动态代理   //基于方法的继承 ????????啥东西 这就不得不提到 静态代理了: 说得高大上,其实就是写一个增强类继承被增强 ...

  9. 23种设计模式——JDK动态代理(AOP)

    文章目录 01 代理 1.1 什么是代理? 1.2 为什么要找中介 02 静态代理 2.1 使用代理模式的作用 2.2 实现代理的方式 2.3 具体实现 2.4 静态代理的优缺点 03 动态代理 3. ...

最新文章

  1. 代码覆盖率原理分析:sys.settrace流程分析
  2. 如何把选择屏幕放到标准屏幕上
  3. java对数据库的操作_java对数据库的操作(jdbc)
  4. 计算机字符代码表,计算机ASCII码对照表
  5. 【Android手机测试】OOM
  6. html页面上的表格导出为excel文件,Web html table export to excel 网页上的表格数据导出到Excel文件中 使用心得...
  7. cmw500综合测试仪使用_辽宁优质继电器综合测试仪供应商-广州炫通电气科技
  8. 微pe添加网络组件_为微PE添加网络组件win10 64位纯净维护系统集合常见网卡驱动支持BIOS/UEFI量产NVME...
  9. python之读取和写入文件
  10. linux dev 下放的什么意思,详解Linux系统下的/dev目录
  11. RAW格式转存PNG图片
  12. 个人银行账户管理程序(C++)
  13. System.InvalidOperationException:“在应用程序配置文件中找不到名为“LDOAEntities”的连接字符串。”
  14. 卸载精灵(bue directx) r4.0 完美版 绿色
  15. 《数据结构》课程介绍
  16. InputArray和OutputArray的那些事
  17. Centos7创建CA和申请证书
  18. 数学之美 第3章 统计语言模型
  19. 计算机科学报数学竞赛,(word)首届全校数学竞赛.doc
  20. scala编程_Scala可以带回编程的喜悦吗?

热门文章

  1. 计算机专业教师理论培训小结,教师多媒体培训个人心得体会【四篇】
  2. 编程实现:从字符中获取连续数组序列,如字符串a1dl2iad9j3la5kudp7u9pn4blj8ap5u3e6ml9a中可以得到的连续数字序列为1234556.【注】:只考虑一位,因此最长的数
  3. MarkDownPad 2 表格样式修改
  4. TGO鲲鹏会成立三周年,校长霍泰稳发表工作汇报
  5. 天天基金基金经理接口
  6. c语言五子棋卡死,C语言五子棋
  7. 北风网基础+项目实战打造CS高手(C#系列培训)
  8. 蓝桥杯嵌入式G431学习之SysTick定时器中断
  9. 【vincent's blog】vincent's 博客园
  10. 第一次作业:对计算机学科学习的规划和探讨