代理模式是一种设计模式,能够使得在不修改源目标的前提下,额外扩展源目标的功能。即通过访问源目标的代理类,再由代理类去访问源目标。这样一来,要扩展功能,就无需修改源目标的代码了。只需要在代理类上增加就可以了。
其实代理模式的核心思想就是这么简单,在java中,代理又分静态代理和动态代理2种,其中动态代理根据不同实现又区分JDK动态代理( 基于接口的的动态代理)和Cglib动态代理(基于子类的动态代理 )。
我们日常见到的spring aop,拦截器,mybatis分页插件,以及日志拦截、事务拦截、权限拦截这些都有动态代理的应用。
静态代理和动态代理的区别
最大的区别静态代理编译期确定的,动态代理在运行期确定的。
静态代理缺点:
冗余:由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
不易维护:一旦接口增加方法,目标对象与代理对象都要进行修改。
生活中常见的代理情况:
租房中介、婚庆公司等
代理模式的两个设计原则:
1. 代理类 与 委托类 具有相似的行为(共同)
2. 代理类增强委托类的行为
静态代理
代理的三要素
a、有共同的行为(结婚) - 接口
b、目标角色(新人) - 实现行为
c、代理角色(婚庆公司) - 实现行为 增强目标对象行为
静态代理的特点
1、目标角色固定
2、在应用程序执行前就得到目标角色
3、代理对象会增强目标对象的行为
4、有可能存在多个代理 引起"类爆炸"(缺点)
静态代理的实现
定义行为(共同) 定义接口
1 /** 2 * 定义行为 3 */ 4 public interface Marry { 5 public void toMarry(); 6 }
目标对象(实现行为)
1 /** 2 * 静态代理 ——> 目标对象 3 */ 4 public class ZhangSan implements Marry{ 5 // 实现行为 6 @Override 7 public void toMarry() { 8 System.out.println("欢迎来到张三婚礼现场!"); 9 } 10 }
代理对象(实现行为、增强目标对象的行为)
1 /** 2 * 静态代理 ——> 代理对象 3 */ 4 public class MarryCompanyProxy implements Marry { 5 // 目标对象 6 private Marry marry; 7 8 // 通过构造器将目标对象传入 9 public MarryCompanyProxy(Marry marry) { 10 this.marry = marry; 11 } 12 13 // 实现行为 14 @Override 15 public void toMarry() { 16 // 增强行为 17 before(); 18 // 执行目标对象中的方法 19 marry.toMarry(); 20 // 增强行为 21 after(); 22 } 23 24 /** 25 * 增强行为 26 */ 27 private void after() { 28 System.out.println("新婚快乐,早生贵子!"); 29 } 30 31 /** 32 * 增强行为 33 */ 34 private void before() { 35 System.out.println("场地正在布置中..."); 36 } 37 }
通过代理对象实现目标对象的功能