1 课程讲解
1.1 类型:
1.2 定义:
1.3 适用场景:
1.4 优点:
1.5 缺点:
1.6 与其他设计模式关系:
1 课程讲解
1.1 类型:
结构型
1.2 定义:
◆定义:为其他对象提供一种代理,以控制对这个对象的访问
◆代理对象在客户端和目标对象之间起到中介的作用
比喻:目标对象可以理解为房东,客户端代表你,房屋中介代表中介,签合同和水电费缴纳直接找中介就可以。
1.3 适用场景:
◆保护目标对象
◆增强目标对象
1.4 优点:
◆代理模式能将代理对象与真实被调用的目标对象分离
◆一定程度上降低了系统的耦合度,扩展性好
◆保护目标对象
◆增强目标对象
1.5 缺点:
◆代理模式会造成系统设计中类的数目增加
◆在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
◆增加系统的复杂度
1.6 代理模式扩展:
◆静态代理
◆动态代理
◆CGLib代理
静态代理就是在代码中指定显式的代理。
动态代理无法代理类,但是可以代理接口,在jdk动态代理类中类加载是在程序调用到动态代理对象时,才由jvm真正创建,jvm根据传过来的业务类对像和方法名动态的创建了一个代理类的class文件,并且class文件被字节码引擎执行,然后通过该代理类的对像进行方法调用,我们要做的就是把代理类的实现写好。我们更关注的是方法上的增强before 和after增强等。
◆CGLib代理可以代理类.如果业务类没有实现接口,直接定义业务方法的话,无法使用jdk动态代理。
如果接口定义1方法和2方法,实现类自己有3方法,3方法也无法通过jdk进行动态代理
CGLIB代理可以代理实现类,它的原理
如果我们代理一个类,CGLIB会生成一个该类的子类,覆盖其中的方法,(通过继承和重写)。
如果该类是final的,该类不可被继承;如果该类不是final的但是该类的某个方法是final的,该类无法被重写。
所以使用cglib的时候,需要注意final的情况。
静态代理通过在代码中显式的定义了一个业务实现类的一个代理,在代理类中对同名的方法进行包装,用户通过对代理类的被包装过的方法来调用目标对象的业务方法,同时对目标对象的业务方法进行增强。
jdk的动态代理是通过接口中的方法名对在动态生成的代理类中,调用业务实现类的同名方法。注意:必须是接口
cglib是通过继承来实现的,生成的代理类是业务类的子类,通过重写业务方法执行代理。
Spring代理选择-扩展
◆当Bean有实现接口时,Spring就会用JDK的动态代理
◆当Bean没有实现接口时,Spring使用CGlib
◆可以强制使用Cglib
◆在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
◆参考资料:httpsi/docs.spring.io/spring/docs/curent/spring-framework-reference/core.html
代理速度对比-扩展
◆CGLib 底层使用sm字节码生成的,比反射效率要高,
◆JDK动态代理
◆速度对比
执行一样的时候,jdk动态代理要比cglib快百分二十左右。
1.7 与其他设计模式关系:
◆代理模式和装饰者模式
目的不同,装饰者模式是为对象加上行为,而代理模式是控制访问,代理模式更加关注通过控制代理人的方式来增强目标对象。增强对象的方式一般是增强对象的某些行为。
◆代理模式和适配器模式
后者主要改变所要考虑对象的接口,前者是不可以改变所代理类的接口的。