代理模式也叫委托模式,为其他对象提供一种代理以控制对这个对象的访问。状态模式、策略模式、访问者模式本质上是在更特殊的场合采用代理模式。
应用场景
防止直接访问目标对象带来的不必要复杂性 面向切面编程(AOP)
定义
UML图如下: 
实现
Subject类
public interface Subject {
void doSomething();
}
RealSubject类
public class RealSubject implements Subject{
@Override
public void doSomething() {
//业务逻辑
}
}
代理类
public class Proxy implements Subject {
private Subject subject;
public Proxy(){
this.subject = new Proxy();
}
public Proxy(Subject subject){
this.subject = subject;
}
private void before(){
//预处理
}
private void after(){
//后续处理
}
@Override
public void doSomething() {
before();
this.subject.doSomething();
after();
}
}
动态代理
可以发现,在上面代理模式的实现中虽然可以产生代理对象,但是这样做的代价是当要代理多种对象时,就需要为每种对象实现代理对象。为了解决对象量多、代码量大的问题,进一步可拓展为动态代理。

动态代理的实现
InvocationHandler的实现(动态代理核心)
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object object){
this.target = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(this.target,args);
}
}
通知的实现
public interface IAdvice {
void exec();
}
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
//前置通知
}
}
产生动态代理对象
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
//寻找连接点
if(true){
//执行前置通知
(new BeforeAdvice()).exec();
}
//返回结果
return (T) Proxy.newProxyInstance(loader,interfaces,h);
}
}
Client类
public class Client {
public static void main(String[] args) {
Subject subject = new RealSubject();
InvocationHandler handler = new MyInvocationHandler(subject);
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(),handler);
//代理执行
proxy.doSomething();
}
}
整一个调用过程如下:

优点
- 职责清晰,降低系统耦合度
- 高扩展性
缺点
- 增加代理对象,降低请求速度和增加代码
- 动态代理使用到反射,运行效率降低
参考