代理模式
什么是代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
代理模式的意义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式给某一个对象提供一个代理或占位符,并由代理对象来控制对原有对象的访问。
代理模式是一种对象结构型模式。在代理模式中引入了一个新的代理对象,代理对象可以在客户端和目标对象之间起到中介的作用,它去掉客户不能看到的内容和服务或者增添客户需要的额外的新服务。
委托类和代理类的功能
委托类实现真正的业务功能
代理类:
负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等
代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务
例如将项目加入缓存、日志这些功能就可以使用代理类来完成,没必要打开已经封装好的委托类
静态代理 & 动态代理
代理模式可以分为静态代理和动态代理:
静态代理
静态代理是由程序员创建或特定工具自动生成源代码,在程序运行之前,代理类就已经编译生成了.class文件。
优点:
代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合),可以在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:
1)代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
2)代理对象只服务于一种类型的对象,如果要服务多种类型的对象。势必要为每一种对象都进行代理,代理类也得相应修改。
动态代理
动态代理是在程序运行时通过反射机制动态创建的,随用随加载。动态代理常用的有基于接口和基于子类两种方式。
基于接口的动态代理指的是由JDK官方提供的Proxy类,要求被代理类最少实现一个接口,这种方式大大减少了开发人员的开发任务,减少了对业务接口的依赖,降低了耦合度,缺点就是注定有一个共同的父类叫Proxy,Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。
基于子类的动态代理指的是由第三方提供的CGLib,CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以要求被代理类不能用final修饰,即不能是最终类。