动态代理、CGLIB 与 切面编程

来自Wikioe
Eijux讨论 | 贡献2020年10月29日 (四) 01:39的版本 →‎CGLIB
跳到导航 跳到搜索


关于代理

代理,简单说就是:不直接操作对象,而使用代理对象来完成操作;

  • 通过代理对象,可以对原对象进行方法扩展;


代理又可以分为

  1. 静态代理:通过聚合、继承的方式生成代理对象;
    • 代理关系在编译时就确定了
  2. 动态代理:
    • 运行期动态生成代理对象;
    1. Java动态代理:(针对实现了接口的类)
    2. CGLIB:(针对没有实现接口的类)
    3. AspectJ:(springframework的aop基于此实现)

Java动态代理

AspectJ

CGLIB

CGLIB是一个功能强大,高性能的代码生成包。

  • 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制
  • CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。

原理

  1. 动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。
  2. 在子类中采用方法拦截的技术,拦截所有父类方法的调用,并织入横切逻辑。
  • 为没有实现接口的类提供代理,比于JDK动态代理(只能代理接口)更加强大;
  • 不能代理final方法;

CGLIB组成结构

CGLIB组成结构.png

CGLIB底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。

  • 因为使用字节码技术生成代理类,所以CGLIB比java反射的JDK动态代理更快;
  • 关于“ASM”:
    • 除了CGLIB库外,脚本语言(如:“Groovy”、“BeanShell”)也使用ASM生成字节码;
    • ASM使用类似SAX的解析器来实现高性能;
    • (如果直接使用ASM,需要对Java字节码非常了解)

jar包

  • “cglib-nodep-2.2.jar”:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类.
  • “cglib-2.2.jar”:使用此jar包需要关联asm的jar包,否则运行时报错.

类库

CGLIB类库:

  • “net.sf.cglib.core”:底层字节码处理类,他们大部分与ASM有关系;
  • “net.sf.cglib.transform”:编译期或运行期类和类文件的转换;
  • “net.sf.cglib.proxy”:实现创建代理和方法拦截器的类;
  • “net.sf.cglib.reflect”:实现快速反射和C#风格代理的类;
  • “net.sf.cglib.util”:集合排序等工具类;
  • “net.sf.cglib.beans”:JavaBean相关的工具类;

常用的API

命令 说明 示例



使用

  1. public class TargetObject {
        public String method1(String paramName) {
            return paramName;
        }
     
        public int method2(int count) {
            return count;
        }
     
        public int method3(int count) {
            return count;
        }
     
        @Override
        public String toString() {
            return "TargetObject []"+ getClass();
        }
    }