• 23种设计模式之代理模式(动态代理)


    代理模式

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

    代理模式的组成

    • 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
    • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
    • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

    静态代理模式

    动态代理模式

    动态代理的角色和静态代理的一样 .
    动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
    动态代理分为两类 :

    • 一类是基于接口动态代理 , 一类是基于类的动态代理

      • 基于接口的动态代理----JDK动态代理
      • 基于类的动态代理–cglib

      现在用的比较多的是 javasist 来生成动态代理
      我们这里使用JDK的原生代码来实现

    【1】. javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

    JDK的动态代理

    核心 : InvocationHandler类 和 Proxy 类

    • InvocationHandler:调用处理程序
      在这里插入图片描述
    Object invoke(Object proxy, 方法 method, Object[] args)//参数
    //proxy - 调用该方法的代理实例
    //method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
    //args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • Proxy : 代理
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    现在我们通过动态代理模式来实现我们在静态代理中所写实例。


    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //真实角色: 购票者,购票者需要购票
    public class TicketBuyer implements ITicketPurchase{
    
        @Override
        public void buyTicket() {
            System.out.println("已经买到票了!");
        }
    
        public static void main(String[] args) {
            //真实角色:购票者的角色,他实现了 购票 的接口;真实角色只需要关注 购票即可,
            //而不需要去关注购票的具体过程,即将大象塞进冰箱一样,我们只提供三步即可!
            TicketBuyer ticketBuyer = new TicketBuyer();
    
            //代理实例的调用处理程序;
            //可以理解为 购票窗口
            BuyTicket buyTicket = new BuyTicket();
    
            //代理对象需要知道他为谁而代理,即我们去窗口买票的时候,需要提供身份证
            buyTicket.setTicketBuyer(ticketBuyer); //将真实角色放置进去!
    
            //创建一个代理的对象,让代理对象去帮我们处理购票的具体过程
            //可以理解为具体的 操作员
            ITicketPurchase proxy = (ITicketPurchase)buyTicket.getProxy(); //动态生成对应的代理类!
            //操作员 去执行 具体的购票流程
            proxy.buyTicket();
        }
    }
    
    //抽象角色: 购票
    interface ITicketPurchase{
        void buyTicket();
    }
    
    //代理角色 : 购票站
    class BuyTicket implements InvocationHandler {
    
        private TicketBuyer ticketBuyer;
    
        public void setTicketBuyer(TicketBuyer ticketBuyer) {
            this.ticketBuyer = ticketBuyer;
        }
    
        //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    ticketBuyer.getClass().getInterfaces(),this);
        }
    
        // proxy : 代理类 method : 代理类的调用处理程序的方法对象.
        // 处理代理实例上的方法调用并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            before();
            //核心:本质利用反射实现!
            //回去执行被代理对象的方法,即执行购票者ticketBuyer的 buyTicket()方法,并且返回该方法的值;
            Object result = method.invoke(ticketBuyer, args);
            after();
            return result;
        }
    
        //购票之前
        private void before() {
            System.out.println("查询是否有票...");
            System.out.println("提交购票申请...");
            System.out.println("付钱...");
            System.out.println("出票...");
        }
    
        //完成购票之后
        private void after() {
            System.out.println("打印发票,提供给购票者!");
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    在这里插入图片描述


    核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!

    如果我们需要编写一个通用的动态代理实现的类!所有的代理对象设置为Object即可!

    动态代理的好处

    • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .

    • 公共的业务由代理来完成 . 实现了业务的分工 ,

    • 公共业务发生扩展时变得更加集中和方便 .

    • 一个动态代理 , 一般代理某一类业务

    • 一个动态代理可以代理多个类,代理的是接口!


    动态代理模式 狂神说

  • 相关阅读:
    【Unity入门计划】利用Cinemachine实现简单的相机跟随&设置相机边界
    Tomcat多实例和负载均衡动静分离
    多线程开发中,多用消息传递,少用锁
    如何只使用TD跟踪微分器改进普通PID控制(附完整梯形图代码)
    【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
    React学习笔记(一)
    【20220903-美团笔试】
    熟练利用切片操作
    视频需求超平常数 10 倍,却节省 60% 的 IT 成本投入是种什么样体验?
    微擎模块 志汇同城微圈小程序10.9.5开源版
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/126212771