代理模式[转][整理]
代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
1. 抽象角色:声明真实对象和代理对象的共同接口,(并非必需的,使用cglib实现代理时,可以不申明抽象角色);
2. 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
3. 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
以下以《Java与模式》中的示例为例:
//抽象角色: abstract public class Subject{ abstract public void request(); }
//真实角色:实现了Subject的request()方法。 public class RealSubject extends Subject{ public RealSubject(){ } public void request(){ System.out.println("From real subject."); } }
//代理角色: public class ProxySubject extends Subject{ private RealSubject realSubject; //以真实角色作为代理角色的属性 public ProxySubject(){ } public void request(){ //该方法封装了真实对象的request方法 preRequest(); // 调用真实角色前的处理 if( realSubject == null ){ realSubject = new RealSubject(); } realSubject.request(); //此处执行真实对象的request方法 postRequest(); // 调用真实角色后的处理 } private void preRequest(){ //something you want to do before requesting } private void postRequest(){ //something you want to do after requesting } }
// 使用场景public class ProxyTest { public static void main(String[] args) { Subject sub=new ProxySubject(); Sub.request(); }}
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
public interface Subject{ public void request(); }
public class RealSubject implements Subject{ public RealSubject(){ } public void request(){ System.out.println("From real subject."); } }
public class ProxySubject implements InvocationHandler { private Object target; public ProxySubject(Object obj) { this.target = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling " + method); Object result = method.invoke(this.target, args); System.out.println("after calling " + method); return result;proxyRs } /** * 提供一个静态方法,获取动态代理实例 */ public static Object createProxyInstance(Object obj) { Assert.notNull(obj); Class<?> clz = obj.getClass(); /* 以下是分解步骤 Class c = Proxy.getProxyClass(clz.getClassLoader(),clz.getInterfaces()); Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class}); Subject subject =(Subject) ct.newInstance(new Object[]{new MyInvocationHandler(obj)}); */ //以下是一次性生成 return Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), new DynamicSubject(obj)); }}
// 使用场景public class ProxyTest { public static void main(String[] args) throws Throwable { RealSubject rs = new RealSubject(); // 在这里指定被代理类 Subject subject = (Subject) DynamicSubject.createProxyInstance(rs);// 获取代理类 subject.request(); }}
//真实角色:实现了Subject的request()方法。 public class RealSubject { public RealSubject(){ } public void request(){ System.out.println("From real subject."); } }
public class CGLIBProxyFactory implements MethodInterceptor { private Object target; public CGLIBProxyFactory(Object obj) { this.target = obj; } public static Object creatNewProxyInstance(Object obj) { CGLIBProxyFactory proxy = new CGLIBProxyFactory(obj); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(proxy.getTarget().getClass()); ////代理类会生产一个被代理类的子类,final方法除外 enhancer.setCallback(proxy);//将CGLIBProxyFactory实例设为回调对象,必须实现接口 MehtoInterceptor return enhancer.create(); } //代理对象被回调的时候调用此方法 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("before calling " + method); Object result = methodProxy.invoke(this.target, args); System.out.println("after calling " + method); return result; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; }}
// 使用场景public class ProxyTest { public static void main(String[] args) throws Throwable { RealSubject rs = new RealSubject(); RealSubject proxyRs = (RealSubject) CGLIBProxyFactory.creatNewProxyInstance(rs); proxyRs.request(); }}