JDK 动态代理和 CGLib 动态代理区别

1. 代理方式

  • JDK 动态代理

    • 只支持接口代理。它通过反射机制生成一个实现了指定接口的代理类。
    • 代理对象只能调用接口中定义的方法。
  • CGLib 动态代理

    • 通过继承方式生成代理类。它可以代理没有实现接口的类。
    • 代理对象可以调用类中的所有方法(除了final方法)。

2. 性能

  • JDK 动态代理

    • 由于是基于接口的代理,相对简单,性能较好。
  • CGLib 动态代理

    • 由于需要生成一个子类,性能相对较低,但在许多情况下仍然足够快。

3. 使用场景

  • JDK 动态代理

    • 适用于需要代理接口的场景,特别是在 Spring AOP 中,通常使用 JDK 动态代理来处理接口。
  • CGLib 动态代理

    • 适用于需要代理具体类的场景,尤其是在类没有实现接口时。CGLib 也常用于需要对类进行增强的情况。

4. 代理对象的创建

  • JDK 动态代理

    • 使用java.lang.reflect.Proxy类创建代理对象。
    MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
        MyInterface.class.getClassLoader(),
        new Class<?>[]{MyInterface.class},
        new MyInvocationHandler(realObject)
    );
    
  • CGLib 动态代理

    • 使用net.sf.cglib.proxy.Enhancer类创建代理对象。
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(MyClass.class);
    enhancer.setCallback(new MyMethodInterceptor());
    MyClass proxy = (MyClass) enhancer.create();
    

5. 代理类的生成

  • JDK 动态代理

    • 生成的代理类在运行时创建,内存占用相对较小。
  • CGLib 动态代理

    • 生成的代理类是一个子类,可能会占用更多内存。

6. 总结

  • JDK 动态代理

    • 通过反射实现、只支持接口代理、代理对象只能调用接口中定义的方法
    • 性能较好
    • 使用java.lang.reflect.Proxy类创建代理对象
    • 内存占用相对较小
  • CGLib 动态代理

    • 通过继承实现、可以代理没有实现接口的类、代理对象可以调用类中的所有方法(除了final方法)
    • 性能相对较低
    • 使用net.sf.cglib.proxy.Enhancer类创建代理对象
    • 可能会占用更多内存

参考:ChatGPT

posted @ 2024-09-07 15:57  Higurashi-kagome  阅读(264)  评论(0)    收藏  举报