代理模式学习

简介

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

  • 作用
    • 代理模式的作用是,为其他对象提供一种代理,在不改变接口的前提下,以控制对这个对象的访问
  • 角色
    • 代理模式一般涉及到3个角色:抽象角色(接口)、代理角色、被代理角色
  • 类型
    • 静态代理、动态代理(jdk代理、CGLIB代理)

静态代理

代理类、被代理类需要实现相同的接口,或者继承相同的父类

  • 接口

    package cn.proxy.statictest;
    
    public interface Person {
        void say();
    }
    
  • 被代理类

    package cn.proxy.statictest;
    
    public class Chirld implements Person {
        @Override
        public void say() {
            System.out.println("i am liangzilun");
        }
    }
    
  • 代理类

    package cn.proxy.statictest;
    
    public class ChirldProxy implements Person {
    
        private Person p;
    
        public ChirldProxy(Person p) {
            this.p = p;
        }
    
        @Override
        public void say() {
            System.out.println("i am heizi");
            p.say();
        }
    }
    
  • 测试类

    package cn.proxy.statictest;
    
    public class StaticProxyTest {
        public static void main(String[] args) {
    
            ChirldProxy chirldProxy = new ChirldProxy(new Chirld());
            chirldProxy.say();
        }
    }
    

可以看到可以在不改变 被代理类的情况下,增加一些功能。

  • 缺陷
    • 被代理类须已经存在,而且作为代理类的内部属性
    • 每个业务类都要一个代理类,如果业务量庞大,会导致类急剧膨胀
    • 如果接口修改,代理类和被代理类也需要跟着修改,不易维护。

动态代理(JDK代理)

  • 代理类是在程序运行期间由JVM根据反射等机制动态生成的。

  • 被代理类须实现接口

  • 接口类

    package cn.proxy.dynamicproxy;
    
    public interface Person {
        void say();
    }
    
  • 被代理类

    package cn.proxy.dynamicproxy;
    
    public class Chirld implements Person {
        @Override
        public void say() {
            System.out.println("i am liangzilun");
        }
    }
    
  • jdk代理

    package cn.proxy.dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class DynamicProxy implements InvocationHandler {
        private Object target;
    
        public DynamicProxy(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("i am heizi");
            method.invoke(target,args);
            return null;
        }
    
        // 返回动态代理 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
        public <T> T getProxy(){
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    }
    
  • 测试

    package cn.proxy.dynamicproxy;
    
    public class DynamicProxyTest {
        public static void main(String[] args) {
    
            DynamicProxy dynamicProxy = new DynamicProxy(new Chirld());
            Person proxy = dynamicProxy.getProxy();
            proxy.say();
        }
    }
    

参考

posted @ 2020-09-24 15:45  depycode  阅读(118)  评论(0编辑  收藏  举报