设计模式之动态代理
2010-08-16 20:32
316 查看
静态代理和动态代理同属于代理模式,作用是一样的,只是在实现起来是不同的,动态代理,也就是说代理是动态生成的。
package viekie.du.proxy;
public interface Moveable {
public void move();
}
Car这个类是需要被代理的对象
package viekie.du.proxy;
import java.util.Random;
public class Car implements Moveable {
@Override
public void move() {
System.out.println("car moving");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
InvocationHandler 接口定义了一系列规则接口
package viekie.du.proxy;
import java.lang.reflect.Method;
public interface InvocationHandler {
public void invoke(Object o, Method m
);////Method参数很重要,用来以后通过反射机制动态的调用被代理的对象的m方法
}
TimeHandler 实现这个接口,在invoke方法中定义了规则
package viekie.du.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler{
private Object target;
///////////在处理规则类中拥有一个被代理的对象,以便在invoke方法中利用发射调用m方法
public TimeHandler(Object target) {
this.target = target;
}
@Override
public void invoke(Object o, Method m) {
long start = System.currentTimeMillis();
System.out.println("start time : " + start);
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("total time = " + (end-start));
}
}
Proxy类利用反射机制负责动态的生成代理类,然后将该代理加载到内存。
package viekie.du.proxy;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class Proxy {
public static Object getNewProxyInstance(Class interfaces, InvocationHandler h) throws Exception{
String rt = "/r/n";
String methodString = "";
Method[] methods = interfaces.getMethods();
///查找所有的interface中的方法
for(Method m : methods){
methodString += "@Override" + rt +
"public void " + m.getName() + "() {" + rt +
" try {" + rt +
" Method md = " + interfaces.getName() + ".class.getMethod(/"" + m.getName() + "/");" + rt +
" h.invoke(this, md);" + rt +
" }catch(Exception e) {e.printStackTrace();}" + rt +
"}";
}
String src =
"package viekie.du.proxy;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements " + interfaces.getName() + "{" + rt +
" public $Proxy1(InvocationHandler h) {" + rt +
" this.h = h;" + rt +
" }" + rt +
" viekie.du.proxy.InvocationHandler h;" + rt +
methodString +
"}";
利用拼串的方式生成java文件
,并且写入到硬盘
String fileName = "d:/src/viekie/du/proxy/$Proxy1.java";
File file = new File(fileName);
FileWriter fWriter = new FileWriter(file);
fWriter.write(src);
fWriter.flush();
fWriter.close();
//加载该文件,并且编译
JavaCompiler javaComp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = javaComp.getStandardFileManager(null, null, null);
Iterable iter = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = javaComp.getTask(null, fileMgr, null, null, null, iter);
t.call();
fileMgr.close();
URL[] urls = new URL[]{new URL("file:/" + "d:/src/"
)};/////本地加载
URLClassLoader loader = new URLClassLoader(urls);
Class c = loader.loadClass("viekie.du.proxy.$Proxy1");
Constructor constr = c.getConstructor(InvocationHandler.class);
//利用字节码获取构造方法
return constr.newInstance(h); /// 返回构造对象
}
}
测试类
package viekie.du.proxy;
public class Main {
public static void main(String[] args) throws Exception {
Car t = new Car();
InvocationHandler h = new TimeHandler(t);
Moveable m = (Moveable)Proxy.getNewProxyInstance(Moveable.class, h);
m.move();
}
}
package viekie.du.proxy;
public interface Moveable {
public void move();
}
Car这个类是需要被代理的对象
package viekie.du.proxy;
import java.util.Random;
public class Car implements Moveable {
@Override
public void move() {
System.out.println("car moving");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
InvocationHandler 接口定义了一系列规则接口
package viekie.du.proxy;
import java.lang.reflect.Method;
public interface InvocationHandler {
public void invoke(Object o, Method m
);////Method参数很重要,用来以后通过反射机制动态的调用被代理的对象的m方法
}
TimeHandler 实现这个接口,在invoke方法中定义了规则
package viekie.du.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler{
private Object target;
///////////在处理规则类中拥有一个被代理的对象,以便在invoke方法中利用发射调用m方法
public TimeHandler(Object target) {
this.target = target;
}
@Override
public void invoke(Object o, Method m) {
long start = System.currentTimeMillis();
System.out.println("start time : " + start);
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("total time = " + (end-start));
}
}
Proxy类利用反射机制负责动态的生成代理类,然后将该代理加载到内存。
package viekie.du.proxy;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class Proxy {
public static Object getNewProxyInstance(Class interfaces, InvocationHandler h) throws Exception{
String rt = "/r/n";
String methodString = "";
Method[] methods = interfaces.getMethods();
///查找所有的interface中的方法
for(Method m : methods){
methodString += "@Override" + rt +
"public void " + m.getName() + "() {" + rt +
" try {" + rt +
" Method md = " + interfaces.getName() + ".class.getMethod(/"" + m.getName() + "/");" + rt +
" h.invoke(this, md);" + rt +
" }catch(Exception e) {e.printStackTrace();}" + rt +
"}";
}
String src =
"package viekie.du.proxy;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements " + interfaces.getName() + "{" + rt +
" public $Proxy1(InvocationHandler h) {" + rt +
" this.h = h;" + rt +
" }" + rt +
" viekie.du.proxy.InvocationHandler h;" + rt +
methodString +
"}";
利用拼串的方式生成java文件
,并且写入到硬盘
String fileName = "d:/src/viekie/du/proxy/$Proxy1.java";
File file = new File(fileName);
FileWriter fWriter = new FileWriter(file);
fWriter.write(src);
fWriter.flush();
fWriter.close();
//加载该文件,并且编译
JavaCompiler javaComp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = javaComp.getStandardFileManager(null, null, null);
Iterable iter = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = javaComp.getTask(null, fileMgr, null, null, null, iter);
t.call();
fileMgr.close();
URL[] urls = new URL[]{new URL("file:/" + "d:/src/"
)};/////本地加载
URLClassLoader loader = new URLClassLoader(urls);
Class c = loader.loadClass("viekie.du.proxy.$Proxy1");
Constructor constr = c.getConstructor(InvocationHandler.class);
//利用字节码获取构造方法
return constr.newInstance(h); /// 返回构造对象
}
}
测试类
package viekie.du.proxy;
public class Main {
public static void main(String[] args) throws Exception {
Car t = new Car();
InvocationHandler h = new TimeHandler(t);
Moveable m = (Moveable)Proxy.getNewProxyInstance(Moveable.class, h);
m.move();
}
}
相关文章推荐
- JAVA设计模式--代理模式(动态)(二)
- 设计模式的应用-动态代理实现事务控制
- 设计模式---动态代理(基于JDK的动态代理)
- Java设计模式之----动态代理(二)
- 设计模式:用Java动态代理实现AOP
- java设计模式—动态代理模式
- Java动态代理(设计模式)代码详解
- JAVA设计模式-11-代理模式(动态)(一)
- 设计模式(3)-结构型-代理模式(proxy)以及java动态代理的两种方式
- 代理设计模式之动态代理与静态代理
- 设计模式_001_DynamicProxy(动态代理)
- 反射-动态代理设计模式
- java设计模式之四:代理模式 java静态代理和动态代理
- 设计模式之动态代理
- 设计模式02-动态代理模式
- Java设计模式系列之动态代理模式(转载)
- 【设计模式】动态代理Proxy_01
- 10分钟看懂动态代理设计模式
- 设计模式之动态代理的代码实现(Java)
- 深度解析JAVA动态代理设计模式