博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟JDK动态代理
阅读量:5918 次
发布时间:2019-06-19

本文共 4910 字,大约阅读时间需要 16 分钟。

hot3.png

模拟JDK动态代理 博客分类: java
接口Moveable:public interface Moveable { public void move(); public void stop();}接口的实现类Tank:public class Tank implements Moveable{        public void move() {       System.out.println("tank is moving...");       try {           Thread.sleep(new Random().nextInt(10000));       } catch (InterruptedException e) {           e.printStackTrace();       }    }    @Override    public void stop() {       System.out.println("tank stoped...");    }}模拟的InvocationHandler:public interface InvocationHandler {    public void invoke(Object object,Method method);}InvocationHandler的实现,也即应用类LogHandler:public class LogHandler implements InvocationHandler{    private Object target;//被代理对象    public LogHandler(Object object) {       super();       this.target = object;    }    @Override    public void invoke(Object object,Method method) {       //先调用自己的逻辑,然后调用被代理对象的方法,最后再调用自己的逻辑       System.out.println("log begin...");       try {           method.invoke(target);       } catch (Exception e) {           e.printStackTrace();       }       System.out.println("log end...");    }}本文中最重要的代理类Proxy:public class Proxy {    public static Object newProxyInstance(Class interClass,InvocationHandler handler) throws Exception{       String srcString="";//源代码字符串       String rt = "\r\n";//回车换行符       String methodString = "";//方法字符串       Method[] methods = interClass.getMethods();//找出接口interClass中的所有方法       for(Method method:methods){           //将接口中的所有方法拼接为方法字符串           methodString +=                      "   public void " + method.getName() +"(){" + rt +//方法头部                     "   try{" + rt +                     "      Method md = " +interClass.getName() +".class.getMethod(\"" + method.getName() +"\");" + rt +//获得接口中的一个方法                     "      handler.invoke(this,md);" + rt +//用处理器handler进行处理                     "   }catch(Exception e){" + rt +                     "      e.printStackTrace();" + rt +                     "   }" + rt +                     "   }" + rt ;       }       srcString = "package com.hibernate.proxy;" + rt +                  "import java.lang.reflect.Method;" + rt +                  "public class $Proxy1 implements "+ interClass.getName() + "{" + rt +//此处应注意:@Proxy1一定要记得实现传过来的接口                  "   private InvocationHandler handler;" + rt +//代理中应该保存一个处理器handler,并在构造函数中进行传递                  "   public $Proxy1(InvocationHandler handler){" +rt +                  "      this.handler = handler;" + rt +                  "   }" + rt +                  methodString + rt +                  "}";       String fileName = System.getProperty("user.dir")+"/src/com/hibernate/proxy/$Proxy1.java";//这个是文件的名称       File file = new File(fileName);//新建文件       if(!file.exists()){           file.createNewFile();       }       FileWriter writer = new FileWriter(file);       writer.write(srcString);//将源代码写到文件中       writer.flush();       writer.close();       //以下的部分是对刚才新建的源代码文件尽心编译       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();       StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);       Iterable units = manager.getJavaFileObjects(fileName);       CompilationTask task = compiler.getTask(null, manager, null, null, null, units);       task.call();       manager.close();       //将编译后的文件加载到内存       URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir"+"/src"))};       URLClassLoader classLoader = new URLClassLoader(urls);       Class class1 = classLoader.loadClass("com.hibernate.proxy.$Proxy1");       //生成新的对象       //获得代理对象$proxy1的构造方法,并将参数的类型传给它       Constructor constructor = class1.getConstructor(InvocationHandler.class);       //构造一个新的代理对象,参数为传进来的handler       Object object = (Object)constructor.newInstance(handler);       //返回新生成的代理对象       return object;    }}测试类:public class ProxyTest {    public static void main(String[] args) {       Tank tank = new Tank();       InvocationHandler handler = new LogHandler(tank);       try {           Moveable moveable = (Moveable)Proxy.newProxyInstance(Moveable.class, handler);//生成一个和被代理对象具有相同接口的代理对象           moveable.move();           moveable.stop();       } catch (Exception e) {           e.printStackTrace();       }    }}编译生成的$Proxy1类:package com.hibernate.proxy;import java.lang.reflect.Method;public class $Proxy1 implements com.hibernate.proxy.Moveable{    private InvocationHandler handler;    public $Proxy1(InvocationHandler handler){       this.handler = handler;    }    public void stop(){    try{       Method md = com.hibernate.proxy.Moveable.class.getMethod("stop");       handler.invoke(this,md);    }catch(Exception e){       e.printStackTrace();    }    }    public void move(){    try{       Method md = com.hibernate.proxy.Moveable.class.getMethod("move");       handler.invoke(this,md);    }catch(Exception e){       e.printStackTrace();    }    } }

 

转载于:https://my.oschina.net/xiaominmin/blog/1598275

你可能感兴趣的文章
分享:这些PHP危险函数,你禁用了吗
查看>>
Linux下apache 2.2.6+php5.2.5+mysql5.0.46+Zend Optim安装详细说明
查看>>
js:实现菜单动态跟随
查看>>
W3School Jquery study
查看>>
聚合数据iOS SDK 快递查询演示示例
查看>>
WebService测试点总结
查看>>
多线程 -线程面试题(一)
查看>>
java序列化(二) - JDK默认序列化
查看>>
CentOS 6.3_ RSync实现文件定时备份同步配置与使用
查看>>
flash的显示列表
查看>>
面向服务与微服务架构
查看>>
PrestaShop加速11招立刻加速PrestaShop外贸电子商务网站无额外插件
查看>>
Linux下查看CPU信息、机器型号等硬件信息命令
查看>>
【Spark亚太研究院系列丛书】Spark实战高手之路-第一章 构建Spark集群(第五步)(6)...
查看>>
队列工厂之RabbitMQ
查看>>
android bluetooth 支持的特性介绍
查看>>
JSON与CSV的转换
查看>>
java中简单常用的JSON生成和解析样例
查看>>
iptables防火墙只允许指定ip连接指定端口、访问指定网站
查看>>
非淡泊无以明志,非宁静无以致远
查看>>