代理模式(proxy)
概念:
为其他对象提供一种代理以控制对这个对象的访问。
优点:
能生成任意接口的代理对象,实现任意的代理
适用:
1. 控制对一个对象的访问权限,用于对象有权限设置的时候
2. 动态添加日志记录
静态代理:
/**
*移动接口
*/
public interface Moveable {
public void move();
}
/**
* 被代理类
*/
public class Tank implements Moveable{
public void move() {
System.out.println("坦克正在开了...");
}
}
/**
* 坦克人代理类
*/
public class TankPersonProxy implements Moveable{
Moveable v; // 聚合
public TankPersonProxy(Moveable v){
this.v = v;
}
public void move() {
System.out.println("坦克里有人上了...");
v.move();
System.out.println("坦克里有人下了...");
}
}
/**
* 坦克时间代理类
*/
public class TankTimeProxy implements Moveable{
Moveable v; // 聚合
public TankTimeProxy(Moveable v){
this.v = v;
}
public void move() {
System.out.println("坦克准备开了...");
v.move();
System.out.println("坦克停下来了...");
}
}
/**
* 代理模式(静态代理)的测试
*/
public class Client {
public static void main(String[] args) {
Moveable m = new Tank();
TankTimeProxy tp = new TankTimeProxy(m);
//TankPersonProxy pp = new TankPersonProxy(tp);
tp.move();
}
}
动态代理模式1:
public interface Moveable {
void move();
}
/**
* 被代理类
*/
public class Tank implements Moveable {
public void move() {
System.out.println("Tank Moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 动态生成代理对象的类
* (只能生成实现了Moveable接口的代理对象)
*/
public class Proxy {
public static Object newProxyInstance() throws Exception{
String rt = "\r\n";
String src =
"package com.hin.proxy_2;" + rt +
"public class TankTimeProxy implements Moveable {" + rt +
" public TankTimeProxy(Moveable t) {" + rt +
" super();" + rt +
" this.t = t;" + rt +
" }" + rt +
" Moveable t;" + rt +
" @Override" + rt +
" public void move() {" + rt +
" long start = System.currentTimeMillis();" + rt +
" System.out.println(\"starttime:\" + start);" + rt +
" t.move();" + rt +
" long end = System.currentTimeMillis();" + rt +
" System.out.println(\"time:\" + (end-start));" + rt +
" }" + rt +
"}";
String fileName = System.getProperty("user.dir")
+ "/src/com/hin/proxy_2/TankTimeProxy.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();
//compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//load into memory and create an instance
URL[] urls = new URL[] {new URL("file:/" + System.getProperty("user.dir") +"/src")};
URLClassLoader ul = new URLClassLoader(urls);
Class c = ul.loadClass("com.hin.proxy_2.TankTimeProxy");
System.out.println(c);
Constructor ctr = c.getConstructor(Moveable.class); // 获得参数为Moveable的构造方法
Moveable m = (Moveable)ctr.newInstance(new Tank());
//m.move();
return m;
}
}
/**
* 动态代理模式的测试_1 (只能对指定的对象,指定的接口方法,实现指定的代理;在Proxy中生成指定的接口的代理对象)
* (在静态代理中,代理对象是要写出来的;而在动态代理中,不用知道代理对象的名字,要的那个代理对象直接帮你产生)
*/
public class Client {
public static void main(String[] args) throws Exception {
//Tank t = new Tank();
Moveable m = (Moveable)Proxy.newProxyInstance();
m.move();
}
}
动态代理模式2:
public interface Moveable {
void move();
}
/**
* 被代理类
*/
public class Tank implements Moveable {
public void move() {
System.out.println("Tank Moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 动态生成代理对象的类(传入接口)
* (能生成任意接口的代理对象)
*/
public class Proxy {
public static Object newProxyInstance(Class infce) throws Exception{
String methodStr = "";
String rt = "\r\n";
Method[] methods = infce.getMethods();
for(Method m : methods){ // 编历接口里面的方法
methodStr += " @Override" + rt +
" public void " + m.getName() + "() {" + rt +
" long start = System.currentTimeMillis();" + rt +
" System.out.println(\"starttime:\" + start);" + rt +
" t." + m.getName() + "();" + rt +
" long end = System.currentTimeMillis();" + rt +
" System.out.println(\"time:\" + (end-start));" + rt +
" }" + rt +
"}";
}
String src =
"package com.hin.proxy_3;" + rt +
"public class TankTimeProxy implements " + infce.getName() + " {" + rt +
" public TankTimeProxy(Moveable t) {" + rt +
" super();" + rt +
" this.t = t;" + rt +
" }" + rt +
" Moveable t;" + rt +
methodStr; // 加上接口里的方法
String fileName = System.getProperty("user.dir")
+ "/src/com/hin/proxy_3/TankTimeProxy.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();
//compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//load into memory and create an instance
URL[] urls = new URL[] {new URL("file:/" + System.getProperty("user.dir") +"/src")};
URLClassLoader ul = new URLClassLoader(urls);
Class c = ul.loadClass("com.hin.proxy_3.TankTimeProxy");
System.out.println(c);
Constructor ctr = c.getConstructor(Moveable.class); // 获得参数为Moveable的构造方法
Object m = ctr.newInstance(new Tank());
//m.move();
return m;
}
}
/**
* 动态代理模式的测试_3 (能生成任意接口的代理对象)
* (在静态代理中,代理对象是要写出来的;而在动态代理中,不用知道代理对象的名字,要的那个代理对象直接帮你产生)
*/
public class Client {
public static void main(String[] args) throws Exception {
//Tank t = new Tank();
Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class);
m.move();
}
}
动态代理3:
public interface Moveable {
void move();
}
/**
* 被代理类(坦克)
*/
public class Tank implements Moveable {
public void move() {
System.out.println("Tank Moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 动态生成代理对象的类(传入接口和处理器)
* (能生成任意接口的代理对象,实现任意的代理)
*/
public class Proxy {
public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception{
String methodStr = "";
String rt = "\r\n";
Method[] methods = infce.getMethods();
for(Method m : methods){ // 编历接口里面的方法
methodStr += " @Override" + rt +
" public void " + m.getName() + "() {" + rt +
" try {" + rt +
" Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
" h.invoke(this, md);" + rt +
" }catch(Exception e) {e.printStackTrace();}" + rt +
" }" + rt +
"}";
}
String src =
"package com.hin.proxy_4;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $proxy1 implements " + infce.getName() + " {" + rt +
" public $proxy1(InvocationHandler h) {" + rt +
" this.h = h;" + rt +
" }" + rt +
" com.hin.proxy_4.InvocationHandler h;" + rt +
methodStr; // 加上接口里的方法
String fileName = System.getProperty("user.dir")
+ "/src/com/hin/proxy_4/$proxy1.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();
//compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//load into memory and create an instance
URL[] urls = new URL[] {new URL("file:/" + System.getProperty("user.dir") +"/src")};
URLClassLoader ul = new URLClassLoader(urls);
Class c = ul.loadClass("com.hin.proxy_4.$proxy1");
System.out.println(c);
Constructor ctr = c.getConstructor(InvocationHandler.class); // 获得参数为Moveable的构造方法
Object m = ctr.newInstance(h);
//m.move();
return m;
}
}
/**
* 处理器接口
*/
public interface InvocationHandler {
/**
* @param o 代理对象
* @param m
*/
public void invoke(Object o, Method m);
}
/**
* 动态代理模式的测试_4 (可以对任意的对象、任意的接口方法,实现任意的代理)
* (目前只能实现一层代理,还没完成叠加的代理)
* (在静态代理中,代理对象是要写出来的;而在动态代理中,不用知道代理对象的名字,要的那个代理对象直接帮你产生)
*/
public class Client {
public static void main(String[] args) throws Exception {
Tank t = new Tank(); // 被代理对象
InvocationHandler h = new TimeHandler(t); // 时间上的代理
Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class, h);
m.move();
}
}