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
浙公网安备 33010602011771号