Java-馬士兵設計模式學習筆記-代理模式--動態代理 修改成可以代理任意接口

一、概述

1.目標:把Proxy修改成可以代理任意接口及其任意方法

2.思路:

(1)代理任意接口:把接口類型作為參數傳給Proxy的newProxyInstance(Class interfze)

(2)代理任意方法:用interfze.getMethods()取出所有方法,拼接實現方法的字符串

?

二、代碼

1.Movable.java

2.Tank.java

3.Proxy.java

4.Client.java

?

1.Movable.java

1 package proxy;
2 
3 public interface Movable {
4     public void move();
5     public void stop();
6 }

?

2.Tank.java

 1 package proxy;
 2 
 3 import java.util.Random;
 4 
 5 public class Tank implements Movable {
 6 
 7     @Override
 8     public void move() {
 9         System.out.println("Tank moving.......");
10         try {
11             Thread.sleep(new Random().nextInt(2000));
12         } catch (InterruptedException e) {
13             e.printStackTrace();
14         }
15     }
16 
17     @Override
18     public void stop() {
19         System.out.println("Tank stopping.......");
20         
21     }
22 
23 }

?

3.Proxy.java

 1 package proxy;
 2 
 3 import java.io.File;
 4 import java.io.FileWriter;
 5 import java.lang.reflect.Constructor;
 6 import java.lang.reflect.Method;
 7 import java.net.URL;
 8 import java.net.URLClassLoader;
 9 
10 import javax.tools.JavaCompiler;
11 import javax.tools.JavaCompiler.CompilationTask;
12 import javax.tools.StandardJavaFileManager;
13 import javax.tools.ToolProvider;
14 
15 public class Proxy {
16 
17     public static Object newProxyInstance(Class interfze) throws Exception {
18         
19         String rt = "\n\r";
20         
21         //拼接"實現接口方法"的字符串
22         String methodStr = "";
23         for(Method m: interfze.getMethods() ){
24             
25             //取出方法的修飾符和返回值類型
26             String [] parts = m.toString().replace("abstract ", "").split("\\.");
27             String [] parts2 = parts[0].split(" ");
28             
29             methodStr +=
30             "@Override" + rt +
31             parts2[0]+" "+parts2[1]+" "+m.getName()+"() {" + rt +
32                 "System.out.println(\"Time Proxy start...........\");" + rt +
33                 "long start = System.currentTimeMillis();" + rt +
34                 "m." + m.getName() + "();" + rt +
35                 "long end = System.currentTimeMillis();" + rt +
36                 "System.out.println(\"花費時間:\"+(end - start));" + rt +
37                 "System.out.println(\"Time Proxy end...........\");" + rt +
38             "}" ;
39         }
40         
41         
42         //動態代理文件的源碼
43         String str = 
44         "package proxy;" + rt +
45 
46         "public class TankTimeProxy implements " + interfze.getName() + " {"+rt+
47 
48             "private " + interfze.getName() + " m;" + rt +
49             
50             "public TankTimeProxy(" + interfze.getName() + " m) {" + rt +
51                 "this.m = m;" + rt +
52             "}" + rt +
53 
54             methodStr + rt +
55 
56         "}" ;
57         
58         //把源碼寫到java文件里
59         File file = new File(System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.java");
60         FileWriter fw = new FileWriter(file);
61         fw.write(str);
62         fw.flush();
63         fw.close();
64         
65         //編譯源碼,生成class,注意編譯環境要換成jdk才有compiler,單純的jre沒有compiler,會空指針錯誤
66         JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
67         
68         //文件管事器
69         StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);
70         
71         //編譯單元
72         Iterable units = fileMgr.getJavaFileObjects(file);
73         
74         //編譯任務
75         CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);
76         
77         //編譯
78         t.call();    
79         fileMgr.close();
80         
81         //把類load到內存里
82         URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.class")};
83         URLClassLoader uc = new URLClassLoader(urls);
84         Class c = uc.loadClass("proxy.TankTimeProxy");
85         
86         //生成實例
87         //return c.newInstance(); //c.newInstance()會調用無參數的Construtor,若類沒有無參的Constructor時會出錯
88         Constructor ctr = c.getConstructor(interfze);
89         return ctr.newInstance(new Tank());
90     }
91 }

?

4.Client.java

 1 package proxy;
 2 
 3 import java.io.IOException;
 4 
 5 import org.junit.Test;
 6 
 7 public class Client {
 8 
 9     @Test
10     public void testProxy() throws Exception{
11         
12         Movable m = (Movable)Proxy.newProxyInstance(Movable.class);
13         m.move();
14         m.stop();
15         
16     }
17 }

?

三、運行結果

轉載于:https://www.cnblogs.com/shamgod/p/4592359.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374932.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374932.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374932.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PTA習題

PTA習題 PTA浙大版《C語言程序設計(第3版)》 題目集5-6 水仙花數是指一個N位正整數(N≥3),它的每個位上的數字的N次冪之和等于它本身。 本題要求編寫兩個函數,一個判斷給定整數是否水仙花數,…

acdream 1409 Musical 狀壓DP

鏈接:http://acdream.info/problem?pid1409 題意:整個國家有n座城市,每座城市有三種粉絲。 第一種一周看一場音樂劇,挑選的音樂劇是已經在周圍城市播放上演過的次數最多的音樂劇中的隨機一個。 另外一種每天看一場音樂劇&#xf…

真正的模塊化Web應用程序:為什么沒有開發標準?

OSGI , SpringSource , Jboss模塊 ,J2EE和清單永遠不會結束。所有這些技術都向他們的最終用戶/開發人員保證了相同的東西,或多或少是Java模塊化Web應用程序(?)。 但是,我們當中有多少…

C語言5-7習題

本題要求實現一個函數&#xff0c;用下列公式求cos(x)的近似值&#xff0c;精確到最后一項的絕對值小于e&#xff1a; #include <stdio.h> #include <math.h>double funcos( double e, double x );int main() { double e, x;scanf("%lf %lf", &…

JDBC批處理executeBatch

JDBC運行SQL聲明&#xff0c;有兩個處理接口&#xff0c;一PreparedStatement,Statement,一般程序JDBC有多少仍然比較PreparedStatement 只要運行批處理&#xff0c;PreparedStatement少一點Statement ps conn.prepareStatement(sql); for(int i 0;i<10;i){ ps.setString(…

BC div2補題以及 復習模除 逆元__BestCoder Round #78 (div.2)

第一題沒話說 智商欠費 加老柴輔導終于過了 需要在意的是數據范圍為2的63次方-1 三個數相加肯定爆了 四邊形的定義  任意邊小于其余三邊之和 換句話說就是  最長邊小于其余三邊之和 這樣的話問題轉化為 最長邊依次減其余三邊的結果是否小于等于0 還有一點是題目出現0邊 即最…

習題6-1 分類統計字符個數 (15 分)

本題要求實現一個函數&#xff0c;統計給定字符串中英文字母、空格或回車、數字字符和其他字符的個數。 函數接口定義&#xff1a; void StringCount( char s[] );其中 char s[] 是用戶傳入的字符串。函數StringCount須在一行內按照 letter 英文字母個數, blank 空格或回車…

Servlet 3.0異步處理可將服務器吞吐量提高十倍

Servlet是Java中處理服務器端邏輯的主要組件&#xff0c;新的3.0規范引入了一些非常有趣的功能&#xff0c;其中異步處理是最重要的功能之一。 可以利用異步處理來開發高度可伸縮的Web應用程序。 使用此功能可以有效地構建Web 2.0站點和AJAX應用程序。 我們的JCG合作伙伴之一To…

使用secureCRT連接VMware-Ubuntukylin虛擬機

使用SecureCRT連接VMware時總是提醒主機拒絕連接。這時可以使用sudo apt-get install openssh-server openssh-client&#xff0c;在主機上安裝ssh. 安裝成功后&#xff0c;可以連接到主機了。 如果顯示遠程主機拒絕連接。則可以使用如下方法。 VMware里面裝的是Ubuntukylin版本…

加載音頻Audio

var cameraAudio new Audio(); cameraAudio.src camera.wav;// 設置音頻對象的屬性,預加載視頻 var options_audio { preload : auto } for(var key in options_audio){ if(options_audio.hasOwnProperty(key) && (key in cameraAudio)){ cameraAudio[key] opti…

習題6-2 使用函數求特殊a串數列和 (20 分)

給定兩個均不超過9的正整數a和n&#xff0c;要求編寫函數求aaaaaa?aa?a&#xff08;n個a&#xff09;之和。 int fn( int a, int n ); int SumA( int a, int n );其中函數fn須返回的是n個a組成的數字&#xff1b;SumA返回要求的和。 我的代碼&#xff1a; int fn( int a, i…

Java中可怕的雙重檢查鎖定成語

本文討論的問題不是新問題&#xff0c;但即使是經驗豐富的開發人員也仍然很棘手。 單例模式是常見的編程習慣。 但是&#xff0c;當與多個線程一起使用時&#xff0c;必須進行某種類型的同步&#xff0c;以免破壞代碼。 Khangaonkar報告中的 JCG合作伙伴Manoj Khangaonkar在一篇…

國內有哪些好的刷題網站?

http://www.zhihu.com/question/25574458 Luau Lawrence&#xff0c;Data Mining 弱雞 / PhDNTU 溫夢強、石一帆、知乎用戶 等人贊同 - Welcome To PKU JudgeOnline 北京大學的Online Judge。POJ上面的題目有點老了&#xff0c;但好處是做的人多&#xff0c;經典算法題多&…

IE版本判斷

我們常常會在網頁的HTML里面看到形如[if lte IE 9]……[endif]的代碼&#xff0c;表示的是限定某些瀏覽器版本才能執行的語句&#xff0c;那么這些判斷語句的規則是什么呢&#xff1f;請看下文&#xff1a; <!--[if !IE]><!--> 除IE外都可識別 <!--<![endif]…

Js 流程控制

流程控制 順序、分支、循環 順序結構 代碼一行一行從上往下執行并解析 分支結構 if語句 switch語句 if語句 單分支 if(條件表達式){ //語句塊 } 含義&#xff1a;當條件表達式為真的時候就執行里面的語句塊 示例&#xff1a; 雙分支&#xff1a; if(條件表達式){ //語句塊1 }el…

習題6-3 使用函數輸出指定范圍內的完數 (20 分)

本題要求實現一個計算整數因子和的簡單函數&#xff0c;并利用其實現另一個函數&#xff0c;輸出兩正整數m和n&#xff08;0<m≤n≤10000&#xff09;之間的所有完數。所謂完數就是該數恰好等于除自身外的因子之和。例如&#xff1a;6123&#xff0c;其中1、2、3為6的因子。…

速覽Java 7 MethodHandle及其用法

由于Java的Reflection API&#xff0c;我們已經能夠在運行時檢查和更改程序執行。 特別是&#xff0c;我們可以在運行時觀察接口/類/方法和字段&#xff0c;而在編譯時不知道它們的名稱。 JDK 7為這種動態/運行時檢查引入了一個新的參與者&#xff0c;即方法句柄&#xff08;即…

習題6-4 使用函數輸出指定范圍內的Fibonacci數 (20 分)

本題要求實現一個計算Fibonacci數的簡單函數&#xff0c;并利用其實現另一個函數&#xff0c;輸出兩正整數m和n&#xff08;0<m≤n≤10000&#xff09;之間的所有Fibonacci數。所謂Fibonacci數列就是滿足任一項數字是前兩項的和&#xff08;最開始兩項均定義為1&#xff09;…

SmartGWT入門,提供出色的GWT界面

SmartGWT簡介 我最近開始使用SmartGWT &#xff0c;它是一個基于GWT的框架&#xff0c;該框架為您的應用程序UI提供了一個全面的小部件庫&#xff0c;并為服務器端的數據管理提供了幫助。 您可以在SmartGWT展示柜上查看其漂亮的功能。 我準備了一個簡短的“入門”指南&#xf…

Android OpenGL ES(四)----調整屏幕的寬高比

1.寬高比問題 我們現在相當熟悉這樣一個事實&#xff0c;在OpenGL里&#xff0c;我們要渲染的一切物體都要映射到X軸和Y軸上[-1&#xff0c;1]的范圍內&#xff0c;對于Z軸也一樣。這個范圍內的坐標被稱為歸一化設備坐標&#xff0c;其獨立于屏幕實際尺寸或形狀。 不幸的是&…