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.mzph.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;其独立于屏幕实际尺寸或形状。 不幸的是&…