【设计模式-代理模式】

时间:2022-07-24
本文章向大家介绍【设计模式-代理模式】,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【导读】很多场景需要一个中介去完成,例如租房,找工作等。中介会帮你去完成一些其他操作,比如准备合同、与第三方对接等等。此时就需要用到代理模式。

其实Java的动态代理以及spring的CGLib就是用的此模式。

一、定义

为其他对象提供一种代理,以控制对这个对象的访问。比如某些对象的创建比较耗时,就可以使用代理,也可以使用享元模式。

二、实例

有两种方式,一种是静态代理,一种是动态代理。

(1)静态代理

说白了就是在方法执行前后生硬的加上其它处理逻辑。就类似下列代码,在订单保存的前后进行相应的逻辑处理。

public class StaticOrderProxy {

    private OrderService orderService;

    public StaticOrderProxy(OrderService orderService) {
        this.orderService = orderService;
    }

    public int saveOrder(Order order) {
        System.out.println("保存订单之前的处理逻辑");
        int orderId = orderService.saveOrder(order);
        System.out.println("保存订单之后的处理逻辑");
        return orderId;
    }
}

静态代理不适合开闭原则,基本没有扩展性。

(2)动态代理

以JDK的动态代理为例,其代理的类是需要继承接口的,否则会报错。

之前专门有一篇【JDK动态代理源码分析】,感兴趣的可以看一下。

1、必须要有一个类实现InvocationHandler接口

public class DynamicOrderProxy implements InvocationHandler {

    Object target;

    public DynamicOrderProxy(Object target) {
        this.target = target;
    }


    //生成代理类 
    public Object bind(){
        Class<?> aClass = target.getClass();
        return Proxy.newProxyInstance(aClass.getClassLoader(),aClass.getInterfaces(),this);
    }
    /**
     * @param proxy 动态代理实例
     * @param method 需要执行的方法
     * @param args 方法中参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("保存订单之前的逻辑");
        Object result = method.invoke(target, args);
        System.out.println("保存订单之前的逻辑");
        return result;
    }
}

2、需要代理的类

1、接口
public interface OrderService {

    int saveOrder(Order order);

    void test(String a);
}

2、实现类,需要代理的类
public class OrderServiceImpl implements OrderService {

    private OrderDao orderDao ;

    public OrderServiceImpl() {
    }

    public OrderServiceImpl(OrderDao orderDao) {
        this.orderDao = orderDao;
    }

    @Override
    public int saveOrder(Order order) {
        orderDao = new OrderDaoImpl();
        return orderDao.saveOrder(order);
    }
}

3、测试类

OrderService orderService = (OrderService) new DynamicOrderProxy(new OrderServiceImpl()).bind();
Order order = new Order();
order.setOrderId("测试订单号");
orderService.saveOrder(order);

运行结果:

代理模式比较简单。

三、源码实例

(1)JDK动态代理

(2)Spring的AOP