博客
关于我
厚积薄发打卡Day36 :[itcast] GoF23通俗易懂的设计模式之 <代理模式>
阅读量:370 次
发布时间:2019-03-04

本文共 3301 字,大约阅读时间需要 11 分钟。

代理模式

概述

代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问。由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

静态代理

静态代理的特点是代理类在编译期就生成。常见的例子是火车站卖票的场景。顾客通过代售点购买火车票,实际上仍然是火车站卖票。类图如下:

+------------+| 代售点    |+------------+|          || 卖票方法 ||          |+------------+

实例说明:

public interface SellTickets {    void sell();}public class TrainStation implements SellTickets {    public void sell() {        System.out.println("火车站卖票");    }}public class ProxyPoint implements SellTickets {    private TrainStation station = new TrainStation();    public void sell() {        System.out.println("代理点收取一些服务费用...");        station.sell();    }}public class Client {    public static void main(String[] args) {        ProxyPoint proxyPoint = new ProxyPoint();        proxyPoint.sell();    }}

动态代理

动态代理的特点是代理类在运行时动态生成。Java提供了一个代理类Proxy(JDK1.3提供),用于创建代理对象。Proxy.newProxyInstance方法用于获取代理对象:

public static Object newProxyInstance(ClassLoader loader, Class
[] interfaces, InvocationHandler h) { return Proxy.newProxyInstance(loader, interfaces, h);}

InvocationHandler接口的invoke方法参数说明:

  • proxy:代理对象
  • method:对应于在代理对象上调用的接口方法的Method实例
  • args:代理对象调用接口方法时传递的实际参数

实例说明:

public class ProxyFactory {    private TrainStation station = new TrainStation();    public SellTickets getProxyObject() {        SellTickets sellTickets = (SellTickets) Proxy.newProxyInstance(            station.getClass().getClassLoader(),            station.getClass().getInterfaces(),            new InvocationHandler() {                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                    System.out.println("(jdk动态代理)代售点收取了一定的手续费用...");                    Object result = method.invoke(station, args);                    return result;                }            }        );        return sellTickets;    }}public class Client {    public static void main(String[] args) {        ProxyFactory factory = new ProxyFactory();        SellTickets proxyObject = factory.getProxyObject();        proxyObject.sell();    }}

CGLib动态代理

CGLib是第三方开源库,用于动态代理。它通过生成字节码实现动态代理的效果。在没有接口的情况下,CGLib更适合实现动态代理。它的优点是速度快,但缺点是只能代理非final类。

实例说明:

public class TrainStation {    public void sell() {        System.out.println("火车站卖票");    }}public class ProxyFactory implements MethodInterceptor {    private TrainStation station = new TrainStation();    public TrainStation getProxyObject() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(station.getClass());        enhancer.setCallback(this);        TrainStation obj = (TrainStation) enhancer.create();        return obj;    }    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {        System.out.println("代理点收取一些服务费用(CGLib动态代理方式)...");        return methodProxy.invokeSuper(o, objects);    }}public class Client {    public static void main(String[] args) {        ProxyFactory proxyFactory = new ProxyFactory();        TrainStation proxyObject = proxyFactory.getProxyObject();        proxyObject.sell();    }}

对比

  • JDK代理和CGLib代理:在调用次数较少的情况下,JDK代理效率更高。CGLib在JDK1.6及以上版本效率较低,但在大量调用时表现更好。
  • 动态代理与静态代理:动态代理更灵活,适合接口多变的情况。

优缺点

  • 优点:降低耦合度,保护目标对象,扩展功能。
  • 缺点:增加系统复杂度。

代理与装饰者模式

两者的区别主要在于目的和获取方式:

  • 装饰者:用于增强目标对象功能。
  • 静态代理:用于保护和隐藏目标对象。

应用实例

  • Mybatis:通过MapperProxyFactory实现动态代理。
  • Spring AOP:用于实现AOP编程。

转载地址:http://yhzg.baihongyu.com/

你可能感兴趣的文章
nginx负载均衡的5种策略(转载)
查看>>
nginx负载均衡的五种算法
查看>>
Nginx运维与实战(二)-Https配置
查看>>
Nginx配置ssl实现https
查看>>
Nginx配置TCP代理指南
查看>>
Nginx配置——不记录指定文件类型日志
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
Nginx配置参数中文说明
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
查看>>
NIO ByteBuffer实现原理
查看>>
Nio ByteBuffer组件读写指针切换原理与常用方法
查看>>
NIO Selector实现原理
查看>>
nio 中channel和buffer的基本使用
查看>>
NIO基于UDP协议的网络编程
查看>>
NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
查看>>
Nitrux 3.8 发布!性能全面提升,带来非凡体验
查看>>
NI笔试——大数加法
查看>>
NLog 自定义字段 写入 oracle
查看>>