> 文档中心 > 面试必考之Java的cglib和jdk动态代理对比

面试必考之Java的cglib和jdk动态代理对比


1、作用范围 

    jdk:适用于实现接口的类。主要面向接口。

    cglib:通过继承类的方式来实现,该类应该为非final类型。

2、技术实现

    jdk:实现InvocationHandler横切+反射

    cglib:实现MethodInterceptor

接口。通过修改class文件字节码来对方法进行增强。

3、各jdk版本性能

 1.6,1.7: cglib 优于 jdk

 1.8:  jdk 优于 cglib

 为什么?

cglib通过fastclass来创建类,避免使用反射。

4、技术实现

  这里需要提到字节码和class类的相互生成。

  a. 字节码->class类:classloader

  b. class类->字节码增强:字节码框架asm,Javassist。对应类分别是:classwriterhe 和 classpool。

5、ASM介绍

   watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDogIHnjovpmo_ogYo,size_20,color_FFFFFF,t_70,g_se,x_16

   ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

 说明:asm操作的是jvm汇编指令。

6、Javassist介绍

    Javassist是一个开源的分析、编辑和创建Java字节码的类库。通过使用Javassist对字节码操作为JBoss实现动态AOP框架。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDogIHnjovpmo_ogYo,size_20,color_FFFFFF,t_70,g_se,x_16

7、jdk和cglib比较

   JDK动态代理主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑贬值在一起。

  1)代理模式组成

    subject:实体对象(接口)

    realsubject:真正实体对象(接口实现)

    proxy:代理对象(负责将请求转发到real)

  2)静态代理和动态代理

   静态代理:直接在代理类中调用real类。比较固化。

   动态代理:在动态执行类或方法前后进行所需操作。这些操作交由Invocation Handler处理。

 3)调用方式

      jdk:动态通过proxy调用real。

      cglib:动态通过proxy隐式继承real类。

 4)jdk动态创建机制

      a.获取 RealSubject上的所有接口列表;

       b.确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;

       c.根据需要实现的接口信息,在代码中动态创建 该Proxy类的字节码;

       d.将对应的字节码转换为对应的class 对象;

       e.创建InvocationHandler 实例handler,用来处理Proxy所有方法调用;

       f.Proxy 的class对象 以创建的handler对象为参数,实例化一个proxy对象

  5)cglib动态创建机制

      a.查找类上的所有非final 的public类型的方法定义;

      b.将这些方法的定义转换成字节码;

      c.将组成的字节码转换成相应的代理的class对象;

      d.实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)

huan yhuanhuahuhhttps://mp.weixin.qq.com/s/BWnhRCQLCRa7e_FIL7ofqA