PROXY(代理)-- 对象结构型模式

本文介绍了Java中的代理模式,包括Surrogate动机(如远程代理、虚拟代理和保护代理),展示了如何使用JDK动态代理和CGLIB动态代理来实现代理类,以及与适配器和装饰者模式的区别。
摘要由CSDN通过智能技术生成
  1. 意图
    为其他对象提供一种代理以控制对这个对象的访问

  2. 别名:
    Surrogate

  3. 动机:

  4. 适用性:
    a. 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
    b. 虚代理(Virtual Proxy)根据需要创建开销很大的对象。
    c. 保护代理(Protection Proxy)控制对原始对象的访问。
    d. 只能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。

  5. 结构:
    代理模式结构图

    这是运行时刻一种可能的代理结构的对象图
    代理模式结构图1

  6. 参与者:
    a. Proxy:
    保存一个应用使得代理可以访问实体。
    提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体。
    控制对实体的存取,并可能负责创建和删除它。
    其他功能依赖于代理的类型:
    1)Remote Proxy负责对请求及其参数进行编码,并向不同地址空间中的实体发送已编码的请求。
    2)Virtual Proxy可以缓存实体的附加信息,以便延迟对它的访问。
    3)Protection Proxy检查调用这是否具有实现一个请求所必须的访问权限。
    b. Subject:
    定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
    c. RealSubject:
    定义Proxy所代表的实体。

  7. 协作:
    代理根据其种类,在适当的时候向RealSubject转发请求。

  8. 效果:
    Proxy模式在访问对象时引入了一定程度的间接性。

  9. 实现:

  10. 代码示例:

    public interface Subject {
        void request();
    }

    public class Proxy implements Subject{
        Subject subject;

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

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

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

    public class Client {

        public static void main(String[] args) {
            Proxy proxy = new Proxy(new RealSubject());
            proxy.request();
        }
    }
	
	/**
    * 以下为Java中两种动态代理的方式 JDK动态代理 CGLib动态代理
    */

    /**
    * JDK动态代理
    */

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;

    /**
    * JDK动态代理是Java内置的动态代理工具,动态代理类需要实现InvocationHandler接口,并实现invoke方法。
    */
    public class SubjectInvocationHandler implements InvocationHandler {

        private Object targetObject;

        public SubjectInvocationHandler(Object targetObject) {
            this.targetObject = targetObject;
        }

        /**
        *
        * @param proxy 被代理对象
        * @param method 被代理方法
        * @param args  被代理方法参数
        * @return
        * @throws Throwable
        */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            method.invoke(targetObject, args);
            System.out.println("This is SubjectInvocationHandler invoke()");

            return proxy;
        }
    }

    /**
    * JDKProxy构造类
    */
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;

    @SuppressWarnings("all")
    public class JDKProxy {
        //通过Proxy类的newProxyInstance()方法创建代理类
        public static <T> T getProxyInstance(T object, InvocationHandler handler) {
            return (T) Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), handler);
        }
    }
    
    //客户端调用
    public class Client {

        public static void main(String[] args) {
            Subject subject = new RealSubject();
            SubjectInvocationHandler subjectInvocationHandler = new SubjectInvocationHandler(subject);
            Subject proxyInstance = JDKProxy.getProxyInstance(subject, subjectInvocationHandler);
            proxyInstance.request();
        }
    }

    /**
    * CGLib动态代理
    * 需要引入
    * <dependency>
    *  <groupId>cglib</groupId>
    *  <artifactId>cglib</artifactId>
    *  <version>3.3.0</version>
    * </dependency>
    */

    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;

    import java.lang.reflect.Method;

    /**
    * CGLIB动态代理,需要实现MethodInterceptor,并实现intercept()
    */
    public class SubjectMethodInterceptor implements MethodInterceptor {
        /**
        *
        * @param o 被代理对象
        * @param method 被代理方法
        * @param args 被代理方法参数
        * @param methodProxy 被代理方法的代理对象
        * @return
        * @throws Throwable
        */
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object methodPxy = methodProxy.invokeSuper(o, args);
            System.out.println("This is SubjectMethodInterceptor intercept()");
            return methodPxy;
        }
    }

    /**
    * CGLibProxy构造类
    */
    public class CGLibProxy {
        public static <T> T getProxyInstance(T object, MethodInterceptor methodInterceptor) {
            return (T) Enhancer.create(object.getClass(), methodInterceptor);
        }
    }

    //客户端调用
    public class Client {
        public static void main(String[] args) {
            Subject subject = new RealSubject();
            SubjectMethodInterceptor subjectMethodInterceptor = new SubjectMethodInterceptor();
            Subject proxyInstance = CGLibProxy.getProxyInstance(subject, subjectMethodInterceptor);
            proxyInstance.request();
        }
    }
  1. 已知应用:

  2. 相关模式:
    Adapter:适配器Adapter为它所适配的对象提供了一个不同的接口。
    Decorator:尽管decorator的实现部分与代理相似,当decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值