Java设计模式之代理模式
文章目录
前言
- 掌握代理模式的应用场景和实现原理
 - 了解静态代理和动态代理的区别
 - 了解CGLib和JDK Proxy的根本区别
 - 手写实现动态代理
 
一、代理模式
代理模式(Proxy Pattern)是指为其他对象提供一种代理,以控制对这个对象的访问
 代理对象在客户端和目标对象之间起到中介作用
 根据代理的创建时期,代理模式分为静态代理和动态代理
二、使用场景
- 保护目标对象
 - 增强目标对象
 
三、静态代理
由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。显示声明被代理的对象
 
1. 抽象主题类
/**
 * 抽象主题
 */
public interface ISubject {
    void request();
}
 
2. 真实主题类
/**
 * 真实主题
 */
public class RealSubject implements ISubject {
    @Override
    public void request() {
        System.out.println("真实主题方法");
    }
}
 
3. 代理类
/**
 * 代理类
 */
public class Proxy implements ISubject {
    private RealSubject realSubject;
    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }
    @Override
    public void request() {
        System.out.println("访问前。。。");
        realSubject.request();
        System.out.println("访问后。。。");
    }
}
 
4. 客户端
public class Client {
    public static void main(String[] args) {
        Proxy proxy = new Proxy(new RealSubject());
        proxy.request();
    }
}
 
四、动态代理
在程序运行时,运用反射机制动态创建而成。
 
1. 抽象主题类
/**
 * 抽象主题
 */
public interface ISubject {
    void request();
}
 
2. 真实主题类
/**
 * 真实主题
 */
public class RealSubject implements ISubject {
    @Override
    public void request() {
        System.out.println("真实主题方法");
    }
}
 
3. JDK代理工厂
/**
 * 代理工厂
 */
public class ProxyFactory implements InvocationHandler {
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    public Proxy getTarget() {
        return (Proxy) Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("访问前");
        Object invoke = method.invoke(target, args);
        System.out.println("访问后");
        return invoke;
    }
}
 
4. 客户端
public class Client {
    public static void main(String[] args) {
        ProxyFactory proxy = new ProxyFactory(new RealSubject());
        ISubject target = (ISubject) proxy.getTarget();
        target.request();
    }
}
 
五、CGLib代理
1. 真实主题类
/**
 * 真实主题
 */
public class RealSubject {
    public void request() {
        System.out.println("真实主题方法");
    }
}
 
2. CGLib代理工厂
/**
 * 代理工厂
 */
public class CGLibFactory implements MethodInterceptor {
    public Object getTarget(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("访问前");
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println("访问后");
        return invoke;
    }
}
 
3. 客户端
public class Client {
    public static void main(String[] args) {
        RealSubject target = (RealSubject) new CGLibFactory().getTarget(RealSubject.class);
        target.request();
    }
}
 










