代理设计模式

  • 学习设计模式对我们编写可读性强,扩展性好,耦合度低的代码有很大帮助。比较谁也不想写或接手垃圾代码。
  • 代理模式属于结构型设计模式。在spring中有两个核心模块,其中一个就是AOP切面。它就是使用了动态代理模式对方法进行增强操作。关于代理的定义这里就不在描述了,下面就用官方售票和代理售票的流程模拟三个动态代理实例。

传统代理方案

  • 首先创建一个官方卖票类
/**
 * 官方卖票
 *
 * @Author: ZRH
 * @Date: 2021/2/4 11:46
 */
public class OfficialSell {

    /**
     * 卖票方法
     */
    public void sellingTickets(Integer price) {
        System.err.println("官方售票处收到金额 " + price);
    }
}
  • 创建一个代理售票类
/**
 * 代理售票
 *
 * @Author: ZRH
 * @Date: 2021/2/4 11:54
 */
public class ProxySell {

    private OfficialSell officialSell;

    /**
     * 构造一个官方售票对象
     *
     * @param o
     */
    public ProxySell(OfficialSell o) {
        this.officialSell = o;
    }

    /**
     * 售票方法
     *
     * @param price
     */
    public void sellingTickets(Integer price) {
        System.err.println("代理售票处收费 200");
        Integer money = price - 200;
        officialSell.sellingTickets(money);
    }
}
  • main方法测试代理流程
    /**
     * 传统代理方案
     *
     * @param args
     */
    public static void main(String[] args) {
        Integer price = 1000;
        // 创建一个官方售票对象
        OfficialSell officialSell = new OfficialSell();
        // 创建一个代理售票对象,把官方售票对象放进去
        ProxySell proxySell = new ProxySell(officialSell);
        System.err.println("用户购票金额 " + price);
        proxySell.sellingTickets(price);
    }
  • 结果:
用户购票金额 1000
代理售票处收费 200
官方售票处收到金额 800

JDK动态代理方案

  • 使用JDK动态代理前提是我们必须要有一个接口和接口的实现类
/**
 * 官方卖票
 *
 * @Author: ZRH
 * @Date: 2021/2/4 11:46
 */
public interface OfficialSell {

    /**
     * 卖票方法
     */
    void sellingTickets(Integer price);
}
/**
 * 官方卖票
 *
 * @Author: ZRH
 * @Date: 2021/2/4 11:46
 */
public class OfficialSellImpl implements OfficialSell {

    /**
     * 卖票方法
     */
    @Override
    public void sellingTickets(Integer price) {
        System.err.println("官方售票处收到金额 " + price);
    }
}
  • JDK动态代理主要使用Proxy.newProxyInstance方法创建代理对象实例。三个参数分别是:当前被代理接口的类加载器(目的是使代理类和被代理类用同一类加载器进行加载),被代理类实现的接口列表(这里必须使用接口实现类的实例),InvocationHandler接口的实现类。
/**
 * @Author: ZRH
 * @Date: 2021/2/4 11:56
 */
public class TestMain {

    /**
     * JDK动态代理方案
     *
     * @param args
     */
    public static void main(String[] args) {
        Integer price = 1000;
        System.err.println("用户购票金额 " + price);
        // 定义代理类的类加载器,代理类的接口列表,需要增强代理的实现
        OfficialSell o = (OfficialSell) Proxy.newProxyInstance(OfficialSell.class.getClassLoader(),
                new OfficialSellImpl().getClass().getInterfaces(),
                (proxy, method, args1) -> {
                    if ("sellingTickets".equals(method.getName())) {
                        System.err.println("代理售票处收费 200");
                        Integer price1 = (Integer) args1[0];
                        Integer money = price1 - 200;
                        return method.invoke(new OfficialSellImpl(), money);
                    }
                    return null;
                });
        o.sellingTickets(price);
    }
}
  • 结果:
用户购票金额 1000
代理售票处收费 200
官方售票处收到金额 800

CGLIB动态代理方案

  • CGLIB动态代理是针对一个没有实现接口的类进行的到动态代理。
 /**
 * 官方卖票
 *
 * @Author: ZRH
 * @Date: 2021/2/4 11:46
 */
public class OfficialSell {

    /**
     * 卖票方法
     */
    public void sellingTickets(Integer price) {
        System.err.println("官方售票处收到金额 " + price);
    }
}
  • CGLIB动态代理主要使用Enhancer对象创建代理对象实例。需要注入一个被代理类对象和MethodInterceptor接口的实现类。
/**
 * @Author: ZRH
 * @Date: 2021/2/4 11:56
 */
public class TestMain {

    /**
     * CGLIB动态代理方案
     *
     * @param args
     */
    public static void main(String[] args) {
        Integer price = 1000;
        System.err.println("用户购票金额 " + price);
        final Enhancer enhancer = new Enhancer();
        // 代理类对象
        enhancer.setSuperclass(OfficialSell.class);
        // 需要增强代理的实现
        enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
            if ("sellingTickets".equals(method.getName())) {
                System.err.println("代理售票处收费 200");
                Integer price1 = (Integer) objects[0];
                Integer money = price1 - 200;
                return method.invoke(new OfficialSell(), money);
            }
            return null;
        });
        OfficialSell officialSell = (OfficialSell) enhancer.create();
        officialSell.sellingTickets(price);
    }
}
  • 结果:
用户购票金额 1000
代理售票处收费 200
官方售票处收到金额 800
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值