代理模式总结笔记

Posted 夜守护者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式总结笔记相关的知识,希望对你有一定的参考价值。

代理模式

代理模式定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用

举三个例子:

​ 1:支付宝付款,我们平时付款只要知道付多少钱就行,至于从哪张银行卡上扣钱,由Ali负责

​ 2:结婚时,你只需要和新娘结婚就行,至于布置婚礼场所可以由婚办公司去布置

​ 3:中介,房东出租房子,需要把自己要出租的房子交给中介,让他去出租

  • spring Aop的底层实现是代理模式(动态代理)

    在这里可以考虑下多线程里thread(new thread1()).start()是代理?以及IO中的BufferedReader(FileBufferedReader())是代理?如果不是它们又是什么?

    4:代理模式分类:

    • 静态代理

    • 动态代理
    静态代理:

​ 静态代理有4个角色:

  • 抽象角色: 一般会使用接口或者抽象类去解决

  • 真实角色:被代理的对象

  • 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作

  • 客户:访问代理对象的人

    下面代码以中介为例子(没有写客户,因为客户和房东性质差不多,客户找房子也要去找代理):

    抽象角色:出租房接口

    public interface Rent 
    
    public void rent();
    
    

    真实角色:房东类(实现出租房这个接口)

    public class Host implements Rent
    @Override
    public void rent() 
        // TODO Auto-generated method stub
        System.out.println("房东要出租房子");
    

    代理角色:

    public class Proxy implements Rent
    private Host host;
    
    public Proxy(Host host) 
    this.host = host;
    
    
    @Override
    public void rent() 
    // TODO Auto-generated method stub
    host.rent();
    fare();
    house();
    
    //以下是中介附属的方法,人家不可能无缘无故帮你做的
    public void fare()
     System.out.println("收代理费");
    
    public void house()
     System.out.println("去看房东要出租的房子");
    
    
    

    ​ main类

    public class Main 
    
    /**
    * @Title: main
    * @Description: TODO
    * @param @param args
    * @return void
    * @throws
    */
    public static void main(String[] args) 
        // TODO Auto-generated method stub
    //房东要出租房子,但找不到租房子的人,只能交给代理去做
        Host host=new Host();
    //帮房东赵租房子的人,但会带一些附属操作,人家不可能无缘无故帮你的
         Proxy px=new Proxy(host);
          px.rent();
    

    main方法里也可以用匿名对象写,就像我上面写的多线程那个对象

    动态代理:

    动态代理依靠反射包下(InvocationHandler,proxy)来动态生成一个动态代理类生成的,不是像静态代理那样去直接写好的

    invocationHandler(是一个接口):是由代理实例调用处理程序实现的接口(类似于上面静态里的出租房子那个接口,只是这个接口中有invoke方法,里面利用反射机制,将里面的成分反射成相应的类)

    proxy:提供了创建动态代理类和实例的静态方法

    每个代理实例都有一个关联的调用程序接口,当在代理实例上调用方法时,方法调用将被编码分配到其调用处理程序的invoke()方法

    动态代理分为两大类:基于接口动态代理和基于类的动态代理

    基于接口:依赖于jdk

    基于类:cglib

    角色和静态代理角色一样

    代码演示:

    抽象角色:出租房子接口

    public interface Rent 
    public void rent();
    

    产生代理类的类(动态代理类的对象是抽象透明的,因为本身代理类都是靠里面反射机制产生的):

    public class ProxyInvocationHandler implements InvocationHandler
     //被代理的接口
    private Rent rent;
    
    public void setRent(Rent rent)
        this.rent=rent;
    
    
    //生成得到代理类
    public Object getProxy()
    return  Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
    
    
    //处理代理实例并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        // TODO Auto-generated method stub
        //利用反射机制实现
    Object result=method.invoke(rent, args);
    return result;
    
    
    

    main类

    public class Main 
    public static void main(String[] args) 
        // TODO Auto-generated method stub
        //真实角色
          Host host=new Host();
          //通过调用程序处理角色来处理我们要调用的接口对象
          ProxyInvocationHandler pih=new ProxyInvocationHandler();
          pih.setRent(host);
      /* Proxy.newProxyInstance(this.getClass().getClassLoader(), 
      rent.getClass().getInterfaces(), this);*/
      //getProxy()方法这里有我们的代理的接口,和可以产生代理类的类 
          Rent proxy=(Rent)pih.getProxy();
          proxy.rent();   
    
    
    静态代理优点:

    便于简单业务操作,扩展原功能,不侵入源代码

    缺点:

    容易出现代码冗余,开发效率降低,不利于维护

    静态代理与动态代理比较

    动态代理比较好,它不仅基本上拥有静态代理的优点,

    一个动态代理类可以代理多个真实类pih.setRent(host),只要把里面对象换了便可,但要实现同一个接口
    <!--希望看了此文章的人,如果里面哪里有错了提出来-->

以上是关于代理模式总结笔记的主要内容,如果未能解决你的问题,请参考以下文章

Spring学习笔记--代理

JAVA基础——代理模式

设计模式代理模式 ( 简介 | 适用场景 | 优缺点 | 代理扩展 | 相关设计模式 )

Java静态代理与动态代理模式的实现

08 设计模式 静态代理

设计模式 2 代理模式-静态或者动态