所谓代理,就是一个 人或者一个机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的角色:
- 抽象主题角色:声明了真实主题和代理主题角色的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。
- 代理主题角色:代理主题角色持有真实主题角色的引用,从而可以在任何使用操作真实主题的角色;代理主题角色提供了和真实主题角色相同的接口,以便在任何时候可以替换真实主题角色。
- 真实主题角色:定义了代理角色所代表的真实角色。
/**
* 抽象的主题角色,声明了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题
* @author zhangwei_david
* @version $Id: AbstractTopic.java, v 0.1 2014年10月26日 上午7:52:11 zhangwei_david Exp $
*/
public interface AbstractTopic {
/**
* 请求
*/
public void request();
}
/**
*
* @author zhangwei_david
* @version $Id: RealTopic.java, v 0.1 2014年10月26日 上午7:54:04 zhangwei_david Exp $
*/
public class RealTopic implements AbstractTopic {
/**
* @see com.cathy.demo.pattern.proxy.AbstractTopic#request()
*/
public void request() {
System.out.println("真实主题接收到请求");
}
}
/**
*
* @author zhangwei_david
* @version $Id: ProxyToptic.java, v 0.1 2014年10月26日 上午7:55:01 zhangwei_david Exp $
*/
public class ProxyToptic implements AbstractTopic {
private AbstractTopic realTopic;
/**
* @see com.cathy.demo.pattern.proxy.AbstractTopic#request()
*/
public void request() {
preRequest();
realTopic.request();
}
/**
*
*/
private void preRequest() {
System.out.println("代理角色,前置请求参数检查");
}
public ProxyToptic(AbstractTopic realTopic) {
super();
this.realTopic = realTopic;
}
}
/**
*
* @author zhangwei_david
* @version $Id: Client.java, v 0.1 2014年10月26日 上午7:56:52 zhangwei_david Exp $
*/
public class Client {
/**
*
* @param args
*/
public static void main(String[] args) {
AbstractTopic topic = new ProxyToptic(new RealTopic());
topic.request();
}
}
上述是静态代理模式,代理模式还有动态代理模式:
/**
* 抽象的主题角色
* @author zhangwei_david
* @version $Id: Subject.java, v 0.1 2014年10月21日 下午4:44:11 zhangwei_david Exp $
*/
public interface Subject {
// 抽象的方法
public void request();
}
/**
*
* @author zhangwei_david
* @version $Id: RealSubject.java, v 0.1 2014年10月21日 下午4:45:09 zhangwei_david Exp $
*/
public class RealSubject implements Subject {
/**
* @see com.cathy.demo.pattern.DynamicProxy.Subject#request()
*/
public void request() {
System.out.println("Real request handler");
}
}
/**
*
* @author zhangwei_david
* @version $Id: SubjectHandler.java, v 0.1 2014年10月21日 下午4:55:33 zhangwei_david Exp $
*/
public class SubjectHandler implements InvocationHandler {
private Subject subject;
/**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
System.out.println("Before");
obj = method.invoke(subject, args);
System.out.println("after");
return obj;
}
public SubjectHandler(Subject subject) {
super();
this.subject = subject;
}
}
/**
*
* @author zhangwei_david
* @version $Id: DynamicProxyTest.java, v 0.1 2014年10月21日 下午4:58:50 zhangwei_david Exp $
*/
public class DynamicProxyTest {
/**
*
* @param args
*/
public static void main(String[] args) {
Subject real = new RealSubject();
InvocationHandler handler = new SubjectHandler(real);
ClassLoader cl = Subject.class.getClassLoader();
Subject proxy = (Subject) Proxy.newProxyInstance(cl, real.getClass().getInterfaces(),
handler);
proxy.request();
}
关于CGLIB实现的动态代理模式请参考CGLIB之MethodInterceptor