SpringAOP静态代理和动态代理
代理模式应用于SpringAOP。
传统的静态代理会产生很多代码冗余。目标类和代理类共同实现接口的方法。当我们一个类有很多方法要委托给代理进行执行的时候,或者当我们的目标类有新增了接口的实现方法时,就要不断的修改代理类。这是不合理的,甚至当这些方法的代理逻辑都相同的时候,就会重复很多代码。
为了解决这个问题基于反射机机制的动态代理模式就出现了。动态代理模式分为两种:
1)基于接口的JDK动态代理。
实现InvocationHandler的invoke方法。
客户端使用Java.lang.reflect.Proxy动态代理类产生动态代理类的对象。
newProxyInstance实现过程:获得字节码(getProxyClass0/ClassFactoryProxy/proxygenerator)---创建对象(newInstance)
注意,接口类的Class是一个数组,也就是支持不同的接口的方法。也就是说,代理类在之后就无需修改。
2)基于继承的CGlib的动态代理
如果目标类没有实现接口,那就要选择使用CGLIB来动态代理目标类,有接口也行。
编写织入逻辑方法,要实现MethodInterceptor,重写intercept方法
这里说的继承是让动态产生的代理继承目标类。
setSupperClass() 将代理类继承目标类;
setCallback() 织入代理逻辑方法(实现MethodInterceptor方法)
create() 创建动态代理类
CGLIB会让生成的代理类继承当前对象,
并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。
在CGLIB底层 底层实现是通过ASM字节码处理框架来转换字节码并生成新的代理类
注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
JDK代理和CGlib代理得区别:
JDK基于反射机制,适用于目标类实现接口方法的场景,
CGlib基于继承的形式,获得目标类的所有内容。如果目标类为final、static,则无法继承;如果方法为final、private则也无法使用CGlib.