点 线 面
AOP(Aspect Oriented Programming) 面向方面的编程
基本概念
- Target: 目标,目标类
- Aspect: 跨越多个类的功能层面,比如事务管理、日志管理等等
- Pointcut: 切点,筛选出目标方法,关联一个表达式,即哪些方法是代理范围
- Joinpoint: 连接点,程序执行时间点,比如方法执行时、异常处理时等等
- Advice:增强逻辑,要额外执行的动作
- Before: 时间点前执行,不能阻止时间点执行
- After returning: 时间点无异常完成后执行
- After throwing: 异常后执行
- After(Finally): 时间点后执行,不管有无异常
- Around: 之前之后都处理,最通用最强大的类型
- Weaving: 将增强逻辑引入目标
- 编译时,需要特殊编译器,可以添加源码再编译,也可以编译后针对class文件直接把二进制字节码插入
- 加载时,需要特殊类加载器,加载时添加额外逻辑
- 运行时, 构建动态代理,针对已经加载到JVM的类
- Introduction: 给被代理对象增加额外的方法或属性
静态代理
手动编写维护代理类,代理类和目标实现同一接口
- 每个需要代理的类都需要手动自己进行代理实现,数量多的话需要创建大量代理类文件
- 代理类实现接口,方法多很繁杂并且代码机械重复,而且接口变化如添加方法,代理类也要同步修改
动态代理可以动态生成代理类,无需手动编写,只需要专注于处理逻辑
JDK 动态代理
运行时生成具备一组接口的新类,该类继承了java.lang.reflect.Proxy,由于不能多继承,因此要求必须有接口才行
代理类在调用具体方法时交给handler处理
要求
- 目标对象必须实现了接口
- 需要InvocationHandler内部维护目标对象
生成代理所需参数:目标类的加载器,目标接口数组,处理器
1 | //handler需要实例参与 |
CGLIB 动态代理
CGLIB字节码修改,继承生成子类,重写覆盖方法
1 | //interceptor不需要实例参与 |
注意点
动态代理也会把Object类的hashCode,equals,toString进行代理实现,其他Object方法不会代理作用于代理对象本身
所以代理对象和真实对象是equal的,hashCode和toString也相同
对比
JDK执行性能差,但是创建时间短,需要有接口
CGLIB执行性能好,但是创建时间长,需要能继承子类
只创建一次代理的情况下,比如单例,优先使用CGLIB
应用
- 执行时间统计
- Mock框架
- ORM框架
- IOC容器
- 诊断工具
- 代码生成
一分也是爱~
版权声明
This site by Linest is licensed under a Creative Commons BY-NC-ND 4.0 International License.
由Linest创作并维护的博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。