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 。
  • 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("打印发票,提供给购票者!");
    }


}

在这里插入图片描述


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

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

动态代理的好处

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

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

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

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

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


动态代理模式 狂神说

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈行恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值