本文参考自:http://www.cnblogs.com/qifengshi/p/6566752.html
1. 作用
代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。
为什么要采用这种间接的形式来调用对象呢?一般是因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。
2. 结构
代理模式中的角色
-
统一的抽象类Subject
上层统一的接口或抽象类 -
实际的实现类RealSubject
具体的实现类 -
RealSubject的代理类ProxySubject
具体实现类的代理类
3. 实现
代理模式有两种实现方法,静态代理和动态代理。
静态代理
Subject类
public interface Subject {
void visit();
}
RealSubject类
public class RealSubject implements Subject{
@Override
public void visit() {
System.out.println("this is real subject");
}
}
代理类
public class ProxySubject implements Subject{
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void visit() {
realSubject.visit();
}
}
客户端类
public class StaticProxyPatternMain {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.visit();
}
}
动态代理
动态代理在代理类的构建和代理类对象创建的过程中与静态代理不同,具体如下。
Subject类
public interface Subject {
void visit();
}
RealSubject类
public class RealSubject implements Subject{
@Override
public void visit() {
System.out.println("this is real subject");
}
}
代理类
代理类需要实现InnovationHandler接口,并实现invoke方法,构造函数中传入的对象就对应着具体实现类(RealSubject)的对象
public class ProxySubject implements InvocationHandler{
private Object object;
public ProxySubject(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object, args);
return result;
}
}
客户端类
三个参数的含义
ClassLoader loader表示当前使用到的appClassloader。
Class<?>[] interfaces表示目标对象实现的一组接口。
InvocationHandler h表示当前的InvocationHandler实现实例对象。
public class DynamicProxyPatternMain {
public static void main(String[] args) {
//创建RealSubject
RealSubject realSubject = new RealSubject();
//创建代理类,传入RealSubject对象
ProxySubject proxySubject = new ProxySubject(realSubject);
//获取实现对象的ClassLoader
ClassLoader classLoader = realSubject.getClass().getClassLoader();
/**
* 用Proxy.newProxyInstance创建代理类对象
* 三个参数对应的是
* 具体实现类的ClassLoader
* 一个Class数组,数组中传入抽象类的class对象
* ProxySubject对象
*/
Subject subject =(Subject) Proxy.newProxyInstance(classLoader, new Class[] {Subject.class}, proxySubject);
subject.visit();
}
}