代理模式(Proxy Pattern)

1. 简介

代理模式属于设计模式中的结构型模式,有静态代理和动态代理两种实现方式。代理模式使用代理类来控制访问委托类中方法或者增强委托类的功能。

2. 实现

静态代理

静态代理即是代理类在编译期间已知。

UML类图

UML类图

如上图所示:

  • Subject接口定义了代理类Proxy和委托类RealSubject共同的方法request()
  • RealSubject委托类,它是被代理和控制访问的对象
  • Proxy代理类引用了RealSubject的对象,实现了对它的访问控制

代码实现

interface Subject{
    void request();
}


class RealSubject implements Subject{
    @Override
    public void request() {
        System.out.println("request");
    }

    public void run(){
        System.out.println("run");
    }
}

class Proxy implements Subject{
    private Subject subject;

    public Proxy(Subject subject){
        this.subject = subject;
    }

    @Override
    public void request() {
        System.out.println("before");
        subject.request();
        System.out.println("after");
    }
}

动态代理

动态代理即是代理类在运行期间产生,这个需要用到Java的反射机制,使用JDK的java.lang.reflect这个包中的一个接口和类:

  • InvocationHandler接口是个调用处理器,通过重写invoke(Object proxy, Method method, Object[] args)方法来对委托类中的方法进行控制访问。
  • Proxy类提供几个静态方法:
    • getProxyClass(ClassLoader loader, Class<?>... interfaces)方法通过传入类加载器和委托类实现的接口这些参数来生成一个代理类,生成的代理类继承了Proxy并且实现了所有委托类的接口
    • newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法创建一个代理类实例

代码实现

interface Subject{
    void request();
}

/委托类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("request");
    }

    public void run(){
        System.out.println("run");
    }
}

/调用处理器
class ProxyInvocationHandler implements InvocationHandler{

    private Object realSubject;
    
    public ProxyInvocationHandler(Object realSubject){
        this.realSubject = realSubject;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object returnObject = method.invoke(realSubject, args);
        System.out.println("after");
        return returnObject;
    }
}

class ProxyClass {

    private Class<?> proxy;
    private ProxyInvocationHandler handler;
    private Object realSubject;

    public ProxyClass(ProxyInvocationHandler handler, Object realSubject) {
        this.handler = handler;
        this.realSubject = realSubject;
        this.proxy = productProxyClass();
    }
    
    /产生代理类
    private Class<?> productProxyClass() {
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        Class<?>[] interfaces = realSubject.getClass().getInterfaces();

        return Proxy.getProxyClass(loader, interfaces);
    }

    public Class<?> getProxy() {
        return proxy;
    }

    /创建代理类对象
    public Object newInstance() {
        try {
            Constructor constructor = proxy.getDeclaredConstructor(InvocationHandler.class);
            return constructor.newInstance(handler);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return null;
    }
}

public class DynamicProxy{
    public static void main(String[] args){
        /创建委托类对象
        Subject realSubject = new RealSubject();
        /创建代理类调用处理器
        ProxyInvocationHandler handler = new ProxyInvocationHandler(realSubject);
        
        ProxyClass proxyClass = new ProxyClass(handler, realSubject);
        生成代理类对象
        Subject proxy = (Subject) proxyClass.newInstance();
        
        proxy.request();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容