Java中的代理模式--静态代理和动态代理
代理模式定义:为其他对象提供了一种代理以控制对这个对象的访问。
代理模式的三种角色:
Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject具体主题角色:也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者,Subject接口的实现。
Proxy代理主题角色:也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前做预处理和善后工作。
一句话描述静态代理和动态代理:
静态代理:一个主题类与一个代理类一一对应。
动态代理:多个主题类对应一个代理类。
静态代理的例子:
Subject接口:
package com.design.one; public interface Subject { void doSomething(); }
RealSubject类:
package com.design.one; public class RealSubject implements Subject{ @Override public void doSomething() { System.out.println("doSomething()......"); } }
Proxy类:
package com.design.one; public class Proxy implements Subject{ Subject subject = null; public Proxy(Subject subject) { this.subject = subject; } @Override public void doSomething() { System.out.println("之前"); subject.doSomething(); System.out.println("之后"); } }
Client类:
package com.design.one; public class Client { public static void main(String[] args) { Subject sub = new RealSubject(); Proxy proxy = new Proxy(sub); proxy.doSomething(); } }
输出结果:
之前
doSomething()......
之后
动态代理的例子:
引子:一般来说,使用静态代理,都需要每一个RealSubject编写一一对应的代理类,这些类在编译期间就已经确定了的,如果有多个RealSubject类,但是他们的代理类里面的前处理(“之前”)和后处理(“之后”)是一样的,那么使用静态代理模式为多个RealSubject类编写相同的处理逻辑的代理类就显得臃肿了和多余了。而动态代理不同,它能使多个RealSubject类对应一个代理类,共享“前处理,后处理”功能,动态调用所需主题,大大减小了程序规模。
Subject类:
package com.design.three; public interface Subject { void doSomething(); void doSomething1(); }
Subject2类:
package com.design.three; public interface Subject2 { void doSomething3(); void doSomething4(); }
RealSubject类:
package com.design.three; public class RealSubject implements Subject,Subject2{ @Override public void doSomething() { System.out.println("doSomething()......"); } @Override public void doSomething1() { System.out.println("doSomething()1......"); } @Override public void doSomething3() { System.out.println("doSomething()3......"); } @Override public void doSomething4() { System.out.println("doSomething()4......"); } }
RealSubject2类:
package com.design.three; public class RealSubject2 implements Subject,Subject2{ @Override public void doSomething() { System.out.println("Subject2doSomething()......"); } @Override public void doSomething1() { System.out.println("Subject2doSomething()1......"); } @Override public void doSomething3() { System.out.println("Subject2doSomething()3......"); } @Override public void doSomething4() { System.out.println("Subject2doSomething()4......"); } }
MyInvocationHandler类:
package com.design.three; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler{ private Object obj = null; public MyInvocationHandler(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法前...."); return method.invoke(obj, args); } }
Client类:
package com.design.three; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { Subject sub = new RealSubject();//1 // Subject sub = new RealSubject2();//2 InvocationHandler handler = new MyInvocationHandler(sub); Subject proxy = (Subject) Proxy.newProxyInstance(sub.getClass() .getClassLoader(), sub.getClass().getInterfaces(), handler); proxy.doSomething(); } }
输出结果:
方法前....
doSomething()......
把2注释打开,1注释掉,输出结果:
方法前....
Subject2doSomething()......
接下来是四篇个人认为比较好的学习动态代理的文章,具体原理和分析都在下面了,我就不再累赘了:
上一篇: 设计模式-装饰者模式