1、代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在 执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
1 /* 2 *抽象角色 3 */ 4 public abstract class Subject 5 { 6 public abstract void request(); 7 } 8 9 /* 10 *真实角色 11 */ 12 public class RealSubject extends Subject 13 { 14 public void request() 15 { 16 System.out.println("From real subject."); 17 } 18 } 19 /* 20 *代理角色 21 */ 22 public class ProxySubject extends Subject 23 { 24 private RealSubject realSubject; //代理角色内部引用了真实角色 25 26 public void request() 27 { 28 this.preRequest(); //在真实角色操作之前所附加的操作 29 30 if(null == realSubject) 31 { 32 realSubject = new RealSubject(); 33 } 34 35 realSubject.request(); //真实角色所完成的事情 36 37 this.postRequest(); //在真实角色操作之后所附加的操作 38 } 39 40 private void preRequest() 41 { 42 System.out.println("pre request"); 43 } 44 45 private void postRequest() 46 { 47 System.out.println("post request"); 48 } 49 } 50 /*测试类*/ 51 public class Client 52 { 53 public static void main(String[] args) 54 { 55 Subject subject = new ProxySubject(); 56 57 subject.request(); 58 } 59 }
2、动态代理
1 /* 2 *抽象角色 3 */ 4 package dynamicproxy; 5 6 public interface Subject 7 { 8 public void request(); 9 }
1 /* 2 *真实角色 3 */ 4 package dynamicproxy; 5 6 public class RealSubject implements Subject 7 { 8 public void request() 9 { 10 System.out.println("From real subject!"); 11 } 12 13 }
1 package dynamicproxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 /** 7 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象 8 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要 9 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后 10 * 加入自己的一些额外方法。 11 * 12 */ 13 14 public class DynamicSubject implements InvocationHandler 15 { 16 private Object sub; 17 18 public DynamicSubject(Object obj) 19 { 20 this.sub = obj; 21 } 22 23 public Object invoke(Object proxy, Method method, Object[] args) 24 throws Throwable 25 { 26 System.out.println("before calling: " + method); 27 28 method.invoke(sub, args); 29 30 System.out.println(args == null); 31 32 System.out.println("after calling: " + method); 33 34 return null; 35 } 36 }
1 package dynamicproxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 public class Client 7 { 8 public static void main(String[] args) 9 { 10 RealSubject realSubject = new RealSubject(); 11 12 InvocationHandler handler = new DynamicSubject(realSubject); 13 14 Class<?> classType = handler.getClass(); 15 16 // 下面的代码一次性生成代理 17 18 Subject subject = (Subject) Proxy.newProxyInstance(classType 19 .getClassLoader(), realSubject.getClass().getInterfaces(), 20 handler); 21 22 subject.request(); 23 24 System.out.println(subject.getClass()); 25 26 } 27 }