proxy模式
来源:互联网 发布:辨别产品真假软件 编辑:程序博客网 时间:2024/05/22 06:14
一、定义:为其他对象提供一种代理以控制对这个对象的访问。
二、场景:
(1)系统里有一个BUG,客户发现后,找到支持人员,再由支持人员找到对应的开发。首先找到支持人员,支持人员判断是不是系统BUG可以加一些判断,然后处理由开发人员具体处理,解决以后支持人员又告诉客户你的问题我解决了。
(2)你去超市买东西,其实东西是由工厂生产的,超市就是你和工厂之间的代理。
三、分析:
Spring AOP 声明式事物管理 就是这个应用,代理其实就是“我有前边作点事,我有后边作点事,中间你在作”
一般体现在对于,权限、日志、执行时间等
四、静态代理与动态代理
静态代理:分为聚合和继承
聚合一定比继承好,对于代理的扩展性强。但是静态代理必须知道对于那个需要代理。那如果有许多需要代理,那我需要写很多代理类。
动态代理:对任何类动态的生成代理对象。在内存中生成一份字节码。
五、类图:
静态代理代码
public interface Moveable {void move();}
public class Tank implements Moveable {@Overridepublic void move() {System.out.println("TanK moving........");}}
public class TanklogProxy implements Moveable {private Moveable t;public TanklogProxy(Moveable t) {super();this.t = t;}@Overridepublic void move() {System.out.println("start move........");t.move();System.out.println("end move......");}}
public class TanktimeProxy implements Moveable {private Moveable t;public TanktimeProxy(Moveable t) {super();this.t = t;}@Overridepublic void move() {long time1 = System.currentTimeMillis();System.out.println("time1=" + time1);t.move();long time2 = System.currentTimeMillis();System.out.println("time2=" + time2);System.out.println("运行时间为:" + (time2 - time1));}}
public class TestTank {public static void main(String[] args) {Tank t = new Tank();Moveable move = new TanktimeProxy(t);Moveable movet = new TanklogProxy(move);movet.move();}}
动态代理代码:
public interface InvocationHandler { void invoke(Object o,Method m); }
public class LogInvocationHandler implements InvocationHandler {private Object target;public LogInvocationHandler(Object target) {super();this.target = target;}@Overridepublic void invoke(Object o, Method m) {System.out.println("Tank start...........");try {m.invoke(target);} catch (Exception e) {e.printStackTrace();}System.out.println("Tank stop..............");}}
public interface Moveable {void move();}
public class Tank implements Moveable{ @Override public void move() { int a = 5; int b = 6; int c = 0; int d = 0; for (int i = 0; i < 1000; i++) { d = i; } c = ((a+b)/2)*12; System.out.println("TanK moving..Tank 的速度是"+c); } }
public class Proxy {public static Object newProxyIntenct(Class infac, InvocationHandler h)throws Exception {String br = "\r\n";String methString = "";Method[] method = infac.getMethods();for (Method m : method) {methString = " @Override" + br + " public void " + m.getName()+ "() {" + br + " try {" + br + " Method md ="+ infac.getName() + ".class.getMethod(\"" + m.getName()+ "\");" + br + " h.invoke(this,md);" + br+ " }catch (Exception e){ " + br+ " e.printStackTrace();" + br + " }" + br+ " }";}String src = "package "+infac.getPackage().getName()+";" + br+ "import java.lang.reflect.Method;" + br+ "public class $Proxy implements " + infac.getName() + "{"+ br + " private InvocationHandler h;"+ br + " public $Proxy(InvocationHandler h) {" + br+ " super();" + br + " this.h = h;" + br + " }"+ br + br + methString + br + "}";MakFileUtil.createFile("D:/src/doproxy");// 生成java文件String fileName = "D:\\src\\doproxy\\$Proxy.java";System.out.println(fileName);File file = new File(fileName);FileWriter fWriter = new FileWriter(file);fWriter.write(src);fWriter.flush();fWriter.close();// 生成class文件,jdk6提供的工具类JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();// System.out.println(compiler.getClass().getName());StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);Iterable units = fileManager.getJavaFileObjects(fileName);CompilationTask task = compiler.getTask(null, fileManager, null, null,null, units);task.call();fileManager.close();// 装载到内存,生成新对象URL[] urls = new URL[] { new URL("file:/" + "D:\\src\\") };URLClassLoader loader = new URLClassLoader(urls);Class c = loader.loadClass("doproxy.$Proxy");// 通过有参的构造器反射生成代理类的实例Constructor ctr = c.getConstructor(InvocationHandler.class);Object obj = (Object) ctr.newInstance(h);return obj;}}
public class MakFileUtil {public static void createFile(String pathstr) throws IOException {// 创建多级目录String path = pathstr;// 为指定字符串构造一个 string tokenizer。 "/"字符是分隔标记的分隔符。分隔符字符本身不作为标记。StringTokenizer st = new StringTokenizer(path, "/");String path1 = st.nextToken() + "/";String path2 = path1;while (st.hasMoreTokens()) {path1 = st.nextToken() + "/";path2 += path1;File inbox = new File(path2);if (!inbox.exists())inbox.mkdir();}}}
public class TestTank {public static void main(String[] args) throws Exception {Tank t = new Tank();Moveable moveable = (Moveable) Proxy.newProxyIntenct(Moveable.class,new TimeInvocationHandler(t));Moveable moveable2 = (Moveable) Proxy.newProxyIntenct(Moveable.class,new LogInvocationHandler(moveable));moveable2.move();}}
代理模式装饰者模式的区别
装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能二者的实现机制确实是一样的,可以看到他们的实例代码重复是很多的。但就语义上说,这两者的功能是相反的,模式的一个重要作用是简化其他程序员对你程序的理解,
- Proxy 模式
- proxy模式
- Proxy模式
- Proxy模式
- Proxy模式
- Proxy模式
- Proxy模式
- Proxy 模式
- Proxy模式
- Proxy模式
- proxy 模式
- Proxy模式
- Proxy模式
- Proxy模式
- Proxy 模式
- proxy模式
- Proxy模式
- Proxy 模式
- merge into测试案例
- python服务器和客户端网络通讯UDP
- chmod命令
- 如何使用SSH连接Win7系统+VMware+Ubuntu
- tar命令
- proxy模式
- 《Java程序员上班那点事儿》自我小结1
- 【LeetCode OJ】Sum Root to Leaf Numbers
- !important
- 关于VS 2010 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏解决方案
- pdf格式apk
- chgrp命令
- hdu_2084数塔(动态规划--初步)
- dom4j修改xml