一、概述

1.目标:不自己写代理类,利用Proxy.newProxyInstance()动态生成

2.用到的知识点:

(1)//编译源码,生成class,注意编译环境要换成jdk才有compiler,单纯的jre没有compiler,会空指针错误

JavaCompiler jc = ToolProvider.getSystemJavaCompiler();

(2)//文件管事器
StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);

(3)//编译单元
Iterable units = fileMgr.getJavaFileObjects(file);

(4)//编译任务
CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);

(5)//编译
t.call();

(6)//把类load到内存里

URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.class")};
URLClassLoader uc = new URLClassLoader(urls);
Class c = uc.loadClass("proxy.TankTimeProxy");

(7)//生成实例

//return c.newInstance(); //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
Constructor ctr = c.getConstructor(Movable.class);
return ctr.newInstance(new Tank());

二、代码

1.Movable.java

2.Tank.java

3.Proxy.java

4.Client.java

1.Movable.java

 package proxy;

 public interface Movable {
public void move();
}

2.Tank.java

package proxy;

import java.util.Random;

public class Tank implements Movable {

    @Override
public void move() {
System.out.println("Tank moving.......");
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

3.Proxy.java

 package proxy;

 import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader; import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider; public class Proxy { public static Object newProxyInstance() throws Exception {
String rt = "\n\r"; //动态代理文件的源码
String str =
"package proxy;" + rt + "public class TankTimeProxy implements Movable {"+rt+ "private Movable m;" + rt + "public TankTimeProxy(Movable m) {" + rt +
"this.m = m;" + rt +
"}" + rt + "@Override" + rt +
"public void move() {" + rt +
"System.out.println(\"Time Proxy start...........\");" + rt +
"long start = System.currentTimeMillis();" + rt +
"m.move();" + rt +
"long end = System.currentTimeMillis();" + rt +
"System.out.println(\"花费时间:\"+(end - start));" + rt +
"System.out.println(\"Time Proxy end...........\");" + rt +
"}" + rt + "}" ; //把源码写到java文件里
File file = new File(System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.java");
FileWriter fw = new FileWriter(file);
fw.write(str);
fw.flush();
fw.close(); //编译源码,生成class,注意编译环境要换成jdk才有compiler,单纯的jre没有compiler,会空指针错误
JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); //文件管事器
StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null); //编译单元
Iterable units = fileMgr.getJavaFileObjects(file); //编译任务
CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units); //编译
t.call();
fileMgr.close(); //把类load到内存里
URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.class")};
URLClassLoader uc = new URLClassLoader(urls);
Class c = uc.loadClass("proxy.TankTimeProxy"); //生成实例
//return c.newInstance(); //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
Constructor ctr = c.getConstructor(Movable.class);
return ctr.newInstance(new Tank());
}
}

4.Client.java

 package proxy;

 import java.io.IOException;

 import org.junit.Test;

 public class Client {

     @Test
public void testProxy() throws Exception{ Movable m = (Movable)Proxy.newProxyInstance();
m.move(); }
}

三、运行结果

Java-马士兵设计模式学习笔记-代理模式-动态代理 调用Proxy.newProxyInstance()的更多相关文章

  1. Java-马士兵设计模式学习笔记-桥接模式

    一.概述 1.桥接模式的应用情况:(1)两个维度扩展(2)排列组合 二.代码 1.Gift.java public class Gift { protected GiftImpl giftImpl; ...

  2. Java-马士兵设计模式学习笔记-命令模式

    一.概述 命令模式 二.代码 1.Client.java public class Client { public void request(Server server){ server.addCom ...

  3. Java-马士兵设计模式学习笔记-工厂模式-抽象工厂模式

    一.概述 1.抽象工厂:当情况是需要产生一系列产品,若需更换产品,则要求一系列产品一起换,且要控制一系列产品的产生过程,此时可考虑抽象工厂模式.例:小明装修屋子,把电视.冰箱都替换掉,他这次需要把电视 ...

  4. Java-马士兵设计模式学习笔记-工厂模式-简单工厂

    一.概述 1.目标:要控制任意类型交通工具的生产模式 2.目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多 ...

  5. Java-马士兵设计模式学习笔记-策略模式-模拟 Comparator接口

    续上一篇  <Java 模拟 Comparable接口> 一.Teacher类及Student类的比较大小方式是不固定的,比如老师除了比较职称外,还可比较工龄大小,年龄大小等.则定义Com ...

  6. Java-马士兵设计模式学习笔记-迭代器模式-模仿Collectin ArrayList LinckedList

    Java Iterator模式 Java Iterator模式, 模仿Collectin ArrayList LinckedList 一.有如下几个类 1.接口Collection.java 2.接口 ...

  7. Java-马士兵设计模式学习笔记-建造者模式

    一.概述 二.代码 1.Animal.java public interface Animal { public void bark(); } 2.Dog.java public class Dog ...

  8. Java-马士兵设计模式学习笔记-工厂模式-用Jdom模拟Spring

    一.概述 1.目标:模拟Spring的Ioc 2.用到的知识点:利用jdom的xpath读取xml文件,反射 二.有如下文件: 1.applicationContext.xml <?xml ve ...

  9. Java-马士兵设计模式学习笔记-工厂模式-模拟Spring读取Properties文件

    一.目标:读取properties文件,获得类名来生成对象 二.类 1.Movable.java public interface Movable { void run(); } 2.Car.java ...

  10. Java-马士兵设计模式学习笔记-工厂模式-单例及多例

    一.单例的作用是用于控制类的生成方式,而不让外部类任意new对象 1.Car.java import java.util.ArrayList; import java.util.List; publi ...

随机推荐

  1. Codeforces Round #338 (Div. 2)

    水 A- Bulbs #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1 ...

  2. JSP通过IP获取用户(客户端)的地理位置信息

    <%!//获取客户端的IP public String getRemoteIP(HttpServletRequest request) { if (request.getHeader(" ...

  3. eclipse下Android无法自动生成apk文件怎么办?

    eclipse下Android无法自动生成apk文件怎么办? 现象:创建android工程后,通过手动build/clean或自动build均无法在bin文件夹下生成.apk文件 解决方法:进入win ...

  4. git 学习笔记2--How to create/clone a repository

    1. create/clone 1.1 create 针对已经存在的目录创建一个repository,使用以下命令: git init Initialized empty Git repository ...

  5. HDU1853 Cyclic Tour(最小费用最大流)

    题目大概说给一张有向图,每条边都有权值,要选若干条边使其形成若干个环且图上各个点都属于且只属于其中一个环,问选的边的最少权值和是多少. 各点出度=入度=1的图是若干个环,考虑用最小费用最大流: 每个点 ...

  6. BZOJ3566 : [SHOI2014]概率充电器

    选个根把无根树转化成有根树, 设f[i]表示i不通电的概率 则 答案为对于枚举树根root进行DP后1-f[root]的和 直接算是O(n^2)的,但是n有500000,所以不能过. 对于这样一棵以1 ...

  7. BZOJ3456: 城市规划

    Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或 ...

  8. HDU 1710 二叉树遍历,输入前、中序求后序

    1.HDU  1710  Binary Tree Traversals 2.链接:http://acm.hust.edu.cn/vjudge/problem/33792 3.总结:记录下根结点,再拆分 ...

  9. linux命令之 top, free,ps

    linux终端查看cpu和内存使用情况 t一.op进入全屏实时系统资源使用信息查看 PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 NInice:值 VIRT:进程占 ...

  10. GPIO裸机编程

    作者:李老师,华清远见嵌入式学院讲师. GPIO控制技术是接口技术中最简单的一种.本章通过介绍S5PV210芯片的GPIO控制方法,让读者初步掌握控制硬件接口的方法.本章的主要内容: GPIO功能介绍 ...