麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

深度模擬java動(dòng)態(tài)代理實(shí)現(xiàn)機(jī)制系類之一

2019-11-14 15:37:01
字體:
供稿:網(wǎng)友

上一篇博客是最基本的動(dòng)態(tài)代理原理的實(shí)現(xiàn),因?yàn)槠?span style="color: #ff0000;">固定了接口,固定了代理方法,以及固定了代理的類型,
接下來的博客系類將一步步漸入深度介紹java的動(dòng)態(tài)代理的實(shí)現(xiàn)原理


****************************************************************************
首先補(bǔ)充一下“java代理”的相關(guān)知識(shí),靜態(tài)代理的實(shí)現(xiàn)包括兩種方式,一是聚合,另一種是繼承。
聚合是指通過接口,調(diào)用其實(shí)現(xiàn)類的具體方法:比如接口i,含有方法run(); 類A 實(shí)現(xiàn)了接口i,當(dāng)然
也實(shí)現(xiàn)了方法run(); 類B于是就可以通過new一個(gè)接口 i 的對(duì)象,調(diào)用A的run()方法,并在run()方法前后實(shí)現(xiàn)其他操作,
這樣就實(shí)現(xiàn)了對(duì)A的run()方法的代理;
繼承當(dāng)然更好理解,就是把run()方法重寫,從而實(shí)現(xiàn)代理
但是,一旦代理的操作很多,需要寫的類都非常的繁雜,就需要不斷的寫代理類,不斷的更新代理操作,于是這就有了動(dòng)
態(tài)代理。

*****************************************************************************

這次要對(duì)實(shí)現(xiàn)任意接口的類進(jìn)行代理。

1、接口

public interface Moveable {    void move();}

  



2、被代理的對(duì)象

 1 public class Tank implements Moveable { 2  3     @Override 4     public void move() { 5          6         System.out.); 7         try { 8             Thread.sleep(new Random().nextInt(10000)); 9         } catch (InterruptedException e) {10             e.printStackTrace();11         }12         13     }14     15 }

 


3、用于產(chǎn)生代理對(duì)象

 1 public class Proxy { 2     //產(chǎn)生新的動(dòng)態(tài)代理類 3     public static Object newProxyInstance(Class intf) throws Exception{  //將接口當(dāng)成參數(shù)傳入,這樣就可以代理實(shí)現(xiàn)了任意接口的類,而不僅是實(shí)現(xiàn)了Moveable接口 4         //將一下字符串動(dòng)態(tài)編譯,生成代理類 5         //實(shí)現(xiàn)方式有以下?lián)糁校簀dk6.0 complier API;CGLib;  ASM 6         String rt = "/r/n"; 7         String src = 8                 "public class TankTimeProxy implements " +intf.getName()+ "{"+rt+   //直接用intf,是調(diào)用toString方法,前會(huì)加入字符串 interface 9                         intf.getName()+" t;"+rt+10 11                         "    public TankTimeProxy("+intf.getName()+" t) {"+rt+12                         "    this.t = t;"+rt+13                         "    }"+rt+14 15                         "    @Override"+rt+16                         "    public void move() {"+rt+17                         "        long start = System.currentTimeMillis();"+rt+18                         "        System.out.println(/"start time is /"+start);"+rt+19                         "        t.move();"+rt+20                         "        long end = System.currentTimeMillis();"+rt+21                         "        System.out.println(/"end time is /"+end);"+rt+22                         "        System.out.println(/"time is /"+(end - start));"+rt+23                         "    }"+rt+24                         "}";25 26         //進(jìn)行編譯27         String fileName = "g:/src/TankTimeProxy.java";//將文件另外存儲(chǔ),不放置在工程的默認(rèn)路徑,防止緩沖區(qū)相關(guān)類的沖突28         File f = new File(fileName);29         FileWriter fw = new FileWriter(f);30         //System.out.println(fileName);31         fw.write(src);  //寫入內(nèi)容32 33         fw.flush();34         fw.close();35 36         //進(jìn)行編譯37         //首先獲得編譯器38         //compiler  為java編譯器    javac39         //獲得編譯器對(duì)象40         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();41         //System.out.println(compiler.getClass().getName());//取得類名42         //參數(shù)含義 (編譯診斷,locale,charset)43         //管理動(dòng)態(tài)生成的文件44         StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默認(rèn)值45         //根據(jù)參數(shù)獲取多個(gè)java文件   返回java文件對(duì)象46         Iterable units = fileManager.getJavaFileObjects(fileName);47 48         //“編譯任務(wù)”對(duì)象49         JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);50         task.call();//調(diào)用51         fileManager.close();52 53         //************以上過程獲得了java文件源碼,編譯生成了java文件的class文件*******54         //加載至內(nèi)存,生成新對(duì)象55         //Class.load(0 是加載path路徑的class文件56         //URLClassLoader是將硬盤中的class文件加載進(jìn)入57 58         //通過Url引入本地文件59         URL[] urls = new URL[]{new URL("file:/"+"g:/src/")}; //指定生成class文件的位置,與java文件放置在同一目錄60         //去指定路徑尋找class文件61         URLClassLoader urlClassLoader = new URLClassLoader(urls);62 63         Class c = urlClassLoader.loadClass("TankTimeProxy");64 65         System.out.println(c);66 67         //執(zhí)行68         //c.newInstance(); 是調(diào)用空的構(gòu)造方法69 70         //獲得構(gòu)造方法71         //根據(jù)java虛擬機(jī),每一個(gè)構(gòu)造方法也相當(dāng)于一個(gè)對(duì)象72         Constructor constructor = c.getConstructor(intf);73 74         //產(chǎn)生新對(duì)象75         Moveable m = (Moveable) constructor.newInstance(new Tank());  //new Tank()為構(gòu)造方法的參數(shù)   即被代理對(duì)象76 77         m.move();78 79         return m;80     }81 }

 




4、測(cè)試端

1 public class Client {2     public static void main(String[] args) throws Exception {3 4         //這里任然以Moveable接口為例傳入,因?yàn)樵赑roxy中為節(jié)省麻煩,還是固定生成了Moveable,后來會(huì)慢慢簡(jiǎn)化的,其實(shí)是可以傳遞任意的的接口的5         Moveable m =(Moveable) Proxy.newProxyInstance(Moveable.class);6         m.move();7 8     }9 }

 



5、結(jié)果

(1)生成的java與class文件

(2)java文件的代碼

(3)運(yùn)行結(jié)果


上一篇:JAVA問題集錦Ⅰ

下一篇:Java多線程理解

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 亚洲成年人免费网站 | 一级视频网站 | 线观看免费完整aaa 久久不雅视频 | 玖玖精品视频在线 | 成人区一区二区三区 | 99精品视频一区二区三区 | 久久超 | 亚洲午夜影院在线观看 | 羞羞答答影院 | 巨乳激情 | 极品销魂一区二区三区 | 精品在线观看一区二区三区 | 国产亚洲欧美一区久久久在 | 国产69精品久久久久久久久久 | 亚洲综合视频网 | 黄色片网站在线看 | 日韩视频在线一区二区三区 | 成人在线视频免费播放 | 久久久婷婷一区二区三区不卡 | 午夜精品久久久久久久久久久久久蜜桃 | 黄色成人小视频 | 亚洲天堂在线电影 | 成人偷拍片视频在线观看 | 毛片在线免费视频 | 日韩av有码在线 | 免费中文视频 | 午夜免费一区 | 国产精品一区视频 | 天天草夜夜骑 | 得得啪在线 | 久久爽久久爽久久av东京爽 | 成年免费在线视频 | 视频毛片 | 国产一区二区精品91 | 久久综合综合 | 黄色片快播| 91天堂国产在线 | 亚洲第一成人av | 情侣啪啪网站 | 日韩在线播放一区二区 | 免费国产自久久久久三四区久久 |