代理设计模式

一、概述

代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。
举例:购买保险,不直接购买而是通过代理人购买
​ 购买火车票,自己不去窗口、12306购买 通过黄牛/美团 购买
为什么要采用这种间接的形式来调用对象呢?
1.因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。
2.不改变原程序代码的前提下,对功能进行扩充。通过代理模式,我们可以很方便的给代码添加日志记录,事务控制,权限控制等一系列功能。
对应目标方法增强的公共代码:日志记录,事务控制,权限控制 类似于过滤器

二、静态代理

静态代理:代理只能代理某一类,不能代理多个类

在这里插入图片描述
火车票例子:

/**
 * 火车票
 */
public interface Ticket {

    /**
     * 购买火车票
     */
    void buyTicket();

}



public class TicketBy12306 implements Ticket {

    public void buyTicket() {

        System.out.println("12306 购买火车票");
    }
}
/**
 * 黄牛购买火车票
 *
 * 黄牛:就是一个代理,只能代理 购买火车票
 *      此黄牛为静态代理  对应目标方法的增强  增加日志 多收费用
 */
 public class TicketByHuangNiu implements Ticket {

    private Ticket ticket ;

    public void setTicket(Ticket ticket) {
        this.ticket = ticket;
    }

    /**
     * 黄牛购买火车票 也要通过 12306 购买
     */
    public void buyTicket() {
        System.out.println("黄牛开始抢票");
        ticket.buyTicket();

        System.out.println("黄牛抢票成功,收费200");
    }

}

测试:

public class Test {

    public static void main(String[] args) {


        Ticket ticket =new TicketBy12306();

        // 通过12306 购买火车票
//        ticket.buyTicket();


        TicketByHuangNiu ticketByHuangNiu = new TicketByHuangNiu();

        ticketByHuangNiu.setTicket(ticket);
        //黄牛代理购买火车票
        ticketByHuangNiu.buyTicket();
    }
}

在这里插入图片描述

三、动态代理

一物多用
动态代理就是一个代理可以代理多种 目标对象,对目标对象的方法进行增强

jdk动态代理:

只能代理目标对象实现的接口 不能代理没有接口的目标对象

1、创建目标对象

 // 目标对象
        final Ticket ticket =new TicketBy12306();

2、创建代理对象

  // 创建带代理对象
//        TicketByHuangNiu ticketByHuangNiu = new TicketByHuangNiu();

        // 使用jdk 动态创建代理对象 ********
//        ClassLoader loader,  类加载器  类加载器 将class 加载到内存中,
//        Class<?>[] interfaces, 目标对象 实现的接口
//        InvocationHandler h  当代理对象要 对应的接口方法时 ,会回调(触发invoke方法) ,然后 调用 目标对象的方法

        // 代理对象 只能代理 目标对象对应的接口  Proxy.newProxyInstance
        Ticket ticketHuangNiu = (Ticket) Proxy.newProxyInstance(ticket.getClass().getClassLoader(),
                ticket.getClass().getInterfaces(), new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//                        Object proxy, 当前代理对象
//                        Method method,  执行的方法名
//                        Object[] args 执行方法的参数

                        // 完成 代理 ,对应目标方法的调用
                        System.out.println(" 代理对象开始 调用目标对象");
                        // 让目标对象反射执行
                        Object result =  method.invoke(ticket,args);

                        System.out.println(" 代理对象完成  调用目标对象对应方法并返回结果");

                        return result;
//                        return null;
                    }
                }
        );

3、调用代理对象方法

// 代理对象 调用对应的接口 触发 InvocationHandler 回调
        ticketHuangNiu.buyTicket();

cglib动态代理

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值