Proxy

意图:为其他对象提供一种代理以控制对这个对象的访问。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上.在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层

什么时候使用:想在访问一个类时做一些控制

如何解决 :增加中间层

使用场景:按职责来划分,通常有一下使用场景:1.远程代理 2.虚拟代理 3.Copy-on-Write代理 4.保护(Protect or Access)代理 5.Cache代理 6.防火墙(Firewall)代理 7.同步化(Synchronization)代理 7.智能引用(Smart Reference)代理

注意事项:1.和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理迷失不能改变所代理类的接口 2.和装饰模式的区别:装饰模式为了增强功能,而代理模式是为了加以控制



  1. 模拟Proxy 类
    package com.bjsxt.proxy;
    
    public interface Moveable {
    	void move();
    	
    }
    

    package com.bjsxt.proxy;
    
    import java.util.Random;
    
    
    public class Tank implements Moveable {
    
    	@Override
    	public void move() {
    		
    		System.out.println("Tank Moving...");
    		try {
    			Thread.sleep(new Random().nextInt(10000));
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    	}
    
    	
    	
    }
    

    package com.bjsxt.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 javax.tools.JavaCompiler;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    import javax.tools.JavaCompiler.CompilationTask;
    
    public class Proxy {
    	public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception { //JDK6 Complier API, CGLib, ASM
    		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 +
    						 "}";
    		}
    		*/
    		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 +
    						
    						 "}";
    		}
    		
    		String src = 
    			"package com.bjsxt.proxy;" +  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.bjsxt.proxy.InvocationHandler h;" + rt +
    							
    			methodStr +
    			"}";
    		String fileName = 
    			"d:/src/com/bjsxt/proxy/$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:/" + "d:/src/")};
    		URLClassLoader ul = new URLClassLoader(urls);
    		Class c = ul.loadClass("com.bjsxt.proxy.$Proxy1");
    		System.out.println(c);
    		
    		Constructor ctr = c.getConstructor(InvocationHandler.class);
    		Object m = ctr.newInstance(h);
    		//m.move();
    
    		return m;
    	}
    }
    

    package com.bjsxt.proxy;
    
    import java.lang.reflect.Method;
    
    public interface InvocationHandler {
    	public void invoke(Object o, Method m);
    }
    
    package com.bjsxt.proxy;
    
     import java.lang.reflect.Method;
    
    public class TimeHandler implements InvocationHandler{
    	private Object target;
    	public TimeHandler(Object target) {
    		super();
    		this.target = target;
    	}
    
    	@Override
    	public void invoke(Object o, Method m) {
    		long start = System.currentTimeMillis();
    		System.out.println("starttime:" + start);
    		System.out.println(o.getClass().getName());
    		try {
    			m.invoke(target);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		long end = System.currentTimeMillis();
    		System.out.println("time:" + (end-start));
    	}
    }
     

    package com.bjsxt.proxy;
    
    
    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();
    	}
    }
    //可以对任意的对象、任意的接口方法,实现任意的代理

  2. 用法示例
    package com.bjsxt.proxy.test;
    
    public interface UserMgr {
    	void addUser();
    }
    

    package com.bjsxt.proxy.test;
    
    public class UserMgrImpl implements UserMgr {
    
    	@Override
    	public void addUser() {
    		System.out.println("1: 插入记录到user表");
    		System.out.println("2: 做日志在另外一张表");
    	}
    	
    }
    

    package com.bjsxt.proxy.test;
    
    import java.lang.reflect.Method;
    
    import com.bjsxt.proxy.InvocationHandler;
    
    public class TransactionHandler implements InvocationHandler {
    	
    	private Object target;
    	
    	public TransactionHandler(Object target) {
    		super();
    		this.target = target;
    	}
    
    	@Override
    	public void invoke(Object o, Method m) {
    		System.out.println("Transaction Start");
    		try {
    			m.invoke(target);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		System.out.println("Transaction Commit");
    	}
    
    }
    

    package com.bjsxt.proxy.test;
    
    import com.bjsxt.proxy.InvocationHandler;
    import com.bjsxt.proxy.Proxy;
    import com.bjsxt.proxy.TimeHandler;
    
    public class Client {
    	public static void main(String[] args) throws Exception {
    		UserMgr mgr = new UserMgrImpl();
    		InvocationHandler h = new TransactionHandler(mgr);
    		//TimeHandler h2 = new TimeHandler(h);
    		UserMgr u = (UserMgr)Proxy.newProxyInstance(UserMgr.class,h);
    		u.addUser();
    	}
    }
    



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值