工作之余,最近正好有时间,总结一下java的代理设计模式!本文涉及到的思维导图可以在此链接中下载:
链接:https://pan.baidu.com/s/11XERibKL-Dhpj4NytfcEDQ
提取码:hmvn
一、代理设计模式作用:
对我们的方法前后实现增强
二、应用场景:
1.打印日志
2.AOP
3.事务 Aop
4.Mybatis中 mapper接口
5.全局捕获异常
6.Lcn、seata、分表分框架、shadingjdbc 代理数据源
7.自定义注解生效(反射技术+Aop)
8.Rpc远程调用技术 代理设计模式
三、代理模式的特点:
优点:实现扩展功能,对我们方法实现增强、安全性、冗余性提高代码复用机制。
缺点:生成非常多代理的class文件
四、代理设计模式的分类
静态代理:基于接口实现,需要人工的手写代理类
动态代理:采用程序动态生成代理,不需要程序猿人工手写代理类
Jdk动态代理模式
1.Jdk动态生成的代理类 P r o x y 0 , 注 意 : Proxy0,注意: Proxy0,注意:Proxy0基于接口的方式实现,不能转换为子类。
2.Java的反射机制是无法获取方法的参数名称,只可以获取方法的参数类型。
写JavaJdk动态代理实现思路
1.根据接口的信息动态拼接代理类的源代码 P r o x y . j a v a 2. Proxy.java 2. Proxy.java2.Proxy.java编译为 P r o x y . c l a s s 3. 基 于 类 加 载 器 动 态 读 取 Proxy.class 3.基于类加载器动态读取 Proxy.class3.基于类加载器动态读取Proxy.class到内存中
CGLIB动态代理:采用继承的模式生成代理类 底层基于Asm字节码技术实现生成代理类
1.生成class文件
2.读取去class文件到内存中
3.采用fastClass 索引的机制执行我们的目标方法
注意:Cglib的效率比Jdk动态代理效率要高
原理:使用字节码技术获取当前所有的方法,对每个方法加上一个索引,直接根据索引调用到目标方法效率是比反射机制要高。(使用方法名称+参数类型 计算hash值 在根据hash值得出索引)
五、Spring中是如何综合使用Cglib和Jdk动态代理的?
1.如果被代理类有实现接口的情况下默认采用 Jdk动态代理 可以转换为Cglib
2.如果被代理类没有实现接口的情况下采用Cglib