原写于2010-12-12
一.摘要
1.什么是“代理”
2.代理模式与适配器模式、装饰者模式的区别,适用场景
3.手工代理
4.动态代理的原理
二.什么是“代理”
如:一个CEO,会有一个助理,任何需要CEO处理的事情,都会经过助理过滤、整理后交给CEO。助理就是CEO的代理。
自己理解,代理就是为帮实际的执行者,做数据的过滤和控制,为实际执行者屏蔽掉外部其它因素的影响,专心去做应该做的事情。
三.代理模式与适配器模式、装饰者模式的区别,适用场景
1.代理模式
HeadFirst 定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问。
如上图,代理模式的结构。
适用的场景,如:远程访问、访问权限控制、日志记录等。
2.装饰者模式,IO类图结构如下:
可以从OutputStream à FileOutputStream à BufferedOutputStream,功能依次增强,为对象增加更多的行为。
自己理解:目的不一样,代理是为控制对被代理对象的访问;装饰者,是对被装饰者功能的增强,避免过度使用继承实现不同的功能。
3.适配器模式,其区别从类图即可分辨出来,如下 :
Client请求ExecuteClass,但ExecuteClass暴露的接口不符合client的要求,在双方系统都不修改的情况下,利用适配器模式解决此问题。
三、手工代理
场景:根据id,获取Item;代理检查用户的权限是否有权限查看Item,已经记录log日志。
四、动态代理
对上面的场景,如果使用动态代理,步骤:
1. 根据interface,通过loader,生成Class对象
Class clazz = Proxy.getProxyClass(ItemService.class.getClassLoader(), ItemService.class);
2. 通过反射,获取Class对象的Construct对象(注意:Construct对象需要的参数类型)
Constructor c = clazz.getConstructor(InvocationHandler.class);
3. 调用Construct对象 newInstance()生成实例对象
proxy = (ItemService)c.newInstance(this); //this是InvocationHandler实例
思考问题:实现原理是什么 ?
对于上面场景,实际动态生成的代理的类图。对代理的任何调用都会,super.handle.invoke(),用户实现InvocationHandler,覆写invoke方法,实现基于方法的控制。
从类图,也解释了为什么只能实现“接口”的动态代理,因为代理本身需要继承Proxy,如果实现“类”的代理,意味着要同时继承两个类,与Java不支持多继承相违背。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements Manager { private static Method m1; private static Method m0; private static Method m3; private static Method m2; static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("com.ml.test.Manager").getMethod("modify", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } }
相关推荐
java proxy 代理,全套开发code,带注释,以及相关工具
用sun的JDK API实现java的动态代理类
NULL 博文链接:https://sunlibao123.iteye.com/blog/1837500
深入理解JavaProxy机制.doc
深入理解Java Proxy机制.doc
NULL 博文链接:https://cn-done.iteye.com/blog/1743191
是一个实现了代理服务的类。当有客户端连接时调用serve()方法,可以在客户和服务器端传输数据。
主要介绍了Java Proxy机制详细解读,还是非常不错的,这里分享给大家,需要的朋友可以参考下。
NULL 博文链接:https://lgr310-163-com.iteye.com/blog/686040
NULL 博文链接:https://hello-player.iteye.com/blog/629340
Java动态代理的Demo,讲述动态代理的实现与用途。
我自己用eclipse写的java代码,可以直接用eclipse导入,也可以直接用java -jar proxy_sample.jar执行 代码量很小,尽量通过注释进行说明 本例实现了InvocationHandler接口,代码具有典型性 在研究代理模式(Proxy...
一个用来分析使用HTTP和HTTPS协议的应用程序框架 它的原理很简单,WebScarab记录它检测到的会话内容(请求和应答),使用者可以通过多种形式来查看记录。...也可以用它来调试程序中较难处理的 bug,也可以帮助安全...
java三种代理模式的源码,包含泛型改写
Java 实现免费代理IP的获取方式 并动态实时校验是否有效,java文件项目内含有Jsoup的Jar包(Jsoup是加工过的,含请求),有2个主入口程序: 其一:用于请求代理IP,并立即校验是否是一个有效的代理IP,如果有效,...
JdkProxy.java
JAVA Proxy 代理模式
java-websocket-reverse-proxy 我发现的大多数Java websocket示例都是基于或包含诸如STOMP之类的消息传递协议的。 该示例是研究如何代理任何消息内容而无需担心消息传递协议的结果。 Websocket反向代理的Java实现。 ...
java-selenium-browsermobProxy 一个使用Selenium中的BrowserMob代理捕获网络呼叫的简单示例