代理模式(Proxy Pattern)
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
类型:结构型模式
类图:

由上图代理模式的结构为:
根据代理类的生成时间不同可以将代理分为静态代理和动态代理两种。
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了
代码示例:
1.抽象角色
public interface AbstractSubject { void doSomething(); }
2.代理角色
public class ProxySubject implements AbstractSubject{ private AbstractSubject real ; public ProxySubject(AbstractSubject real) { this.real=real ; } @Override public void doSomething() { real.doSomething(); } public void doOtherthing() { } }
3.真实角色
public class RealSubject implements AbstractSubject{ @Override public void doSomething() { System.out.println( "真实角色被使用" ); } }
4.客户端
public class Client { public static void main(String[] args ) { RealSubject real = new RealSubject(); ProxySubject proxy = new ProxySubject( real ); proxy.doSomething(); } }
5.静态代理的优缺点
优点: 业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 
缺点:
动态代理类的源码是程序在运行期间由JVM根据反射等机制动态生成的,所以不存在代理类的字节码文件。代理角色和真实角色的联系在程序运行时确定。 
1.首先看看和动态代理相关JavaAPI 
要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口:
// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器 static InvocationHandler getInvocationHandler(Object proxy) // 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象 static Class getProxyClass(ClassLoader loader, Class[] interfaces) // 方法 3:该方法用于判断指定类对象是否是一个动态代理类 static boolean isProxyClass(Class cl) // 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例 static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象 // 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行 Object invoke(Object proxy, Method method, Object[] args)
每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象(参见 Proxy 静态方法 4 的第三个参数)。
2.动态代理实现步骤
具体有如下四步骤:
示例代码
1.抽象角色和真实角色代码与上述相同 。 
2. 创建自己的调用处理器:
public class SubjectHandler implements InvocationHandler{ AbstractSubject real; public SubjectHandler(AbstractSubject real){ this.real=real; } @Override public Object invoke(Object obj, Method method, Object[] args)throws Throwable { System.out.println("代理类预处理任务"); //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。 //因为示例程序没有返回值,所以这里忽略了返回值处理 method.invoke(real, args); System.out.println("代理类后续处理任务"); return null; } }
3.客户端 :
public class Client { public static void main(String[] args) { RealSubject real=new RealSubject(); SubjectHandler handler=new SubjectHandler(real); //生成代理类对象 AbstractSubject proxy=(AbstractSubject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{AbstractSubject.class},handler); proxy.doSomething(); } }
4.动态代理的优缺点
优点: 
  动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
缺点: 
  诚然,Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理,原因是多继承在 Java 中本质上就行不通。
原文:http://www.cnblogs.com/Avaoder/p/6321808.html