JDK、CGLIB动态代理实现原理和区别

作者:51IP代理 出处:互联网 时间:2021-03-25
    CGLIB的动态代理与JDK原则
 
    1、jdk动态代理
 
    利用拦截器(拦截器必须实现InvocationHanlder)和反射机制,来生成实现代理接口的匿名类,
 
    InvokeHandler在调用具体方法之前被调用。
    2、cglb型动态代理
 
    利用ASM的开源程序包,将代理对象类的class文件装载在其中,并通过修改它们的字节码来生成子类。
 
    3、JDK或CGLIB什么时候使用?
 
    1) JDK的动态代理默认用于在目标对象实现接口时实现AOP。
 
    2) 当目标对象实现接口时,AOP可以通过CGLIB强制实现。
 
    3) 若目标物件的介面未被执行,必须使用CGLIB库,Spring会自动在JDK动态代理与CGLIB之间转换。
 
    4、我怎样使用CGLIB实现AOP?
 
    (1) 增加CGLIB库(aspectjrt-xxx.jar,aspectjweaver-xxx.jar,cglib-nodep-xxx.jar)
 
    (2) 添加到Spring概要
 
    5、在JDK和CGLIB代码生成字节码之间有什么不同?
 
    1)只有已经实现了接口的类才能生成JDK动态代理,而对于类则不行。
 
    2)CGLIB实现类的代理,主要是为指定的类生成子类,并覆盖子类的方法,重新编写方法实现增强的部分,但是由于类或方法采用继承,所以最好不要声明为final,无法继承final类或方法。
 
    6、cglib是否比JDK快?
 
    1)利用CGLib实现了动态代理,并在CGLib的底层使用了ASM的字节码生成框架,生成了相应的代理类,
 
    jdk6以前比Java反射更有效。唯一需要注意的是,CGLib不能代理声明为final的方法,
 
    根据CGLib的原理,可以动态生成代理类的子类。
 
    2)jdk6,jdk7,jdk8和jdk8在逐步优化JDK动态代理之后比CGLIB代理更高效,因为调用次数更少;
 
    只有当进行大量调用时,jdk6和jdk7的效率才会低于CGLIB代理,但jdk8比CGLIB代理更有效,
 
    总之,jdk代理的效率随着jdk版本的升级而提高,并且CGLIB代理消息也没有跟上。
 
    斯普林如何使用JDK或CGLIB?
 
    7、Spring在Bean实现接口时使用JDK的动态代理
 
    1)如果Bean没有实现接口,Spring就会使用CGlib作为实现
 
    2)可以强制CGlib(添加到spring配置中)
0