八股-动态代理
动态代理
动态代理是一种在程序运行时 (而非编译时) 动态生成代理对象的技术。在不改变原始类的情况下,代理对象可以拦截对目标对象的方法调用,并在调用前后执行一些自定义逻辑/增强。
这里介绍两种动态代理方式:JDK 动态代理、Cglib 动态代理
JDK 动态代理
- JDK 动态代理在运行时动态为目标类所实现的接口,去生成一个实现类(代理类),并实现了接口的所有方法增强代码
- 使用 JDK 动态代理有一个限制:目标类必须实现接口
- 调用时会被代理类拦截,相当于调用到代理类的方法,方法内执行增强逻辑,再通过反射的方式调用目标类的目标方法
Cglib 动态代理
- Cglib 动态代理在运行时动态生成目标类的一个子类,并且重写父类的所有方法增强代码
- Cglib 包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类
- 如果目标类是被 final 修饰的,则不能使用 Cglib 代理,因为 Cglib 是通过继承的方式实现代理
- 调用时会被代理类拦截,相当于调用到代理类的方法,方法内执行增强逻辑,再直接调用父类对应的目标方法
| JDK动态代理 | Cglib动态代理 | |
|---|---|---|
| 原理 | 基于接口生成代理类 | 基于继承生成代理类 |
| 生成代理类速度 | 快 | 慢 |
| 调用过程速度 | 涉及到反射调用目标方法 (略慢) | 调用父类的目标方法(略快) |
| 能否代理没有实现接口的类 | 不能 | 能 |
但随着JDK版本的升级,JDK动态代理的调用过程的速度在不断提升,甚至有可能超过Cglib