静态代理
静态代理就是在程序运行之前,提前写好被代理方法的代理类,编译后运行。在程序运行之前,class已经存在。
动态代理
Java 动态代理是一种在运行时创建代理类的机制,它允许在不提前知道代理类的具体类型的情况下,动态地创建一个代理对象来代替原始类。相比于静态代理,动态代理更加灵活,可以代理任意的接口类型,不需要为每个被代理的类编写专门的代理类,而是通过 Java 的反射机制在运行时动态生成代理类。
动态代理又被称为 JDK 代理或接口代理。
cglib代理
CGLIB(Code Generation Library)是一个开源的第三方库, 采用了非常底层的字节码技术。
CGLIB底层:使用字节码处理框架 ASM,来转换字节码并生成新的类。不鼓励直接使用 ASM,因为它要求你必须对 JVM 内部结构包括 class 文件的格式和指令都很熟悉。
其原理是通过字节码技术动态生成一个要代理类的子类,子类重写要代理类的所有不是 final 的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用 Java 反射的 JDK 动态代理要快。但缺点就是不能代理 final 方法。
JDK 动态代理和 CGLIB 动态代理均是实现 Spring AOP 的基础。
动态代理与 CGLIB 代理的区别
Spring 在 5.X 之前默认的动态代理实现一直是 jdk 动态代理。但是从 5.X 开始,Spring 就开始默认使用 CGLIB 来作为动态代理实现。并且 springboot 从 2.x 开始也转向了 CGLIB 动态代理实现。
区别:
- JDK 动态代理只能基于接口,代理生成的对象只能赋值给接口变量,而 CGLIB 就不存在这个问题,CGLIB 是通过生成子类来实现的,代理对象既可以赋值给实现类,又可以赋值给接口。
- CGLIB 速度比 JDK 动态代理更快,性能更好。