设计模式-代理模式(Proxy)
来源:互联网 发布:释放443端口 仍被占用 编辑:程序博客网 时间:2024/04/27 15:46
代理模式的作用:为其他对象提供一种代理以控制堆这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标之间起到中介的作用。
代理模式角色:
- 抽象角色:声明真实对象和和代理对象的共同接口
- 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
- 真实角色:代理角色所代理的真实对象,是我们最终要引用的对象
静态代理和动态代理的实现:
静态代理
抽象角色:
public interface Subject { void request();}
真实角色:
public class RealSubject implements Subject { @Override public void request() { System.out.println("From real Subject"); }}
代理角色:
public class ProxySubject implements Subject { private RealSubject realSubject; @Override public void request() { this.preRequest(); if (null == realSubject) { realSubject = new RealSubject(); } realSubject.request(); this.postRequest(); } private void preRequest() { System.out.println("pre request"); } private void postRequest() { System.out.println("post request"); }}
测试代码:
public class Client { public static void main(String[] args) { Subject subject = new ProxySubject(); subject.request(); }}
如果按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外如果事先并不知道真实角色,该如何使用代理呢?这个问题我们可以通过java的动态代理类来解决
动态代理
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当做这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你做实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
通过这种方式,被代理的对象(RealSubject)可以在运行时改变,控制的方式(DynamicSubject)也可以动态改变,从而实现了非常灵活的动态代理关系。
public interface Subject { void request();}
public interface Subject1 { void request1();}
public interface Subject2 { void request2(int param1, String param2);}
public class RealSubject implements Subject, Subject1, Subject2 { @Override public void request() { System.out.println("From real subject!"); } @Override public void request1() { System.out.println("From real subject1!"); } @Override public void request2(int param1, String param2) { System.out.println("From real subject2! param1: " + param1 + ",param2:" + param2); }}
public class DynamicSubject implements InvocationHandler { private Object sub; public DynamicSubject(Object sub) { this.sub = sub; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling: " + method); if (args != null) { Arrays.stream(args).forEach(System.out::println); args[0] = (int) args[0] + 1; args[1] = args[1].toString() + " append"; } method.invoke(sub, args); System.out.println("after calling: " + method); return null; }}
public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); InvocationHandler handler = new DynamicSubject(realSubject); Class<?> classType = handler.getClass(); Subject subject = (Subject) Proxy .newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handler); subject.request(); System.out.println(); Subject1 subject1 = (Subject1) Proxy .newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handler); subject1.request1(); System.out.println(); Subject2 subject2 = (Subject2) Proxy .newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handler); subject2.request2(1,"string"); System.out.println(subject2.getClass()); }}
执行结果:
before calling: public abstract void com.huigod.dynamicproxy.Subject.request()From real subject!after calling: public abstract void com.huigod.dynamicproxy.Subject.request()before calling: public abstract void com.huigod.dynamicproxy.Subject1.request1()From real subject1!after calling: public abstract void com.huigod.dynamicproxy.Subject1.request1()before calling: public abstract void com.huigod.dynamicproxy.Subject2.request2(int,java.lang.String)1stringFrom real subject2! param1: 2,param2:string appendafter calling: public abstract void com.huigod.dynamicproxy.Subject2.request2(int,java.lang.String)class com.sun.proxy.$Proxy0
动态代理生成的class是最后打印的$Proxy0类,由于被代理的真实对象实现了不同的接口,所以代理类生成的对象可以由多态性转为每个接口,这个过程需要用到反射的机制。当执行代理类生成的对象任意方法的时候一定会执行代理对象中的invoke方法。
阅读全文
0 0
- 【设计模式】--代理模式 (Proxy模式)
- 代理设计模式(proxy)
- Proxy代理设计模式
- 设计模式 - 代理(Proxy)
- 代理设计模式--Proxy
- Proxy(代理)设计模式
- 代理 proxy 设计模式
- 设计模式之代理模式(Proxy)
- 设计模式之代理模式(Proxy)
- 设计模式--代理模式(Proxy)
- 设计模式--代理模式(Proxy)
- 设计模式-代理模式(Proxy Pattern)
- 设计模式之Proxy(代理模式)
- 设计模式---代理模式(Proxy)
- 设计模式 (九)代理模式(Proxy)
- 设计模式 (九)代理模式(Proxy)
- 设计模式 (九)代理模式(Proxy)
- 【设计模式】之代理模式(Proxy)
- 解决R/RStudio中安装包“无法与服务器建立连接”
- MTK
- Lambda表达式
- 线程1:线程的创建和启动
- 简易shell脚本打造终端字典
- 设计模式-代理模式(Proxy)
- 好的开始是成功的一半
- ProGuard 混淆解析
- Hbase过滤器
- JavaWeb的三层框架
- 面试
- nginx 启动 重载 停止等操作
- Qt学习
- Linux-视频监控系统(10)-对USB摄像头的YUV图片压缩成视频