今天,Java已经卷到“屎上雕花”的程度,八股文的准备如果仅仅靠背诵,很容易陷入“背了忘,忘了背”的死循环中。
所以,我们必须:结合具体的代码demo,尝试系统地掌握,才能更好的卷出一条活路。
Spring AOP(面向切面编程)默认提供了两种动态代理方式:JDK动态代理和CGLIB代理。它们的选择取决于被代理的对象是否实现了接口,以及配置的代理模式。以下是它们的详细区别:
1. JDK动态代理
- 工作原理:JDK动态代理通过反射机制为实现了接口的类生成代理类。在代理类中,方法调用被拦截并转发给对应的
InvocationHandler
进行处理。 - 适用范围:JDK动态代理只能为实现了接口的类创建代理。如果一个类没有实现任何接口,Spring不会使用JDK动态代理。
- 性能:JDK动态代理因为依赖反射,性能相对CGLIB代理略低,但对于简单的接口代理场景,其性能是可以接受的。
2. CGLIB代理
- 工作原理:CGLIB(Code Generation Library)通过生成目标类的子类来实现代理。在子类中,通过重写方法的方式来插入切面逻辑。
- 适用范围:CGLIB代理可以为没有实现接口的类创建代理,因此它适用于那些没有接口的类。然而,CGLIB不能代理
final
类,因为final
类不能被继承,CGLIB的代理机制无法工作。 - 性能:CGLIB代理使用字节码生成技术,性能比JDK动态代理略高,但在生成代理类时可能会耗费更多的时间和内存资源。
3. Spring的选择机制
- 默认情况下,Spring会优先使用JDK动态代理。如果目标类没有实现任何接口,Spring才会退而求其次地使用CGLIB代理。
- 你可以通过配置强制Spring使用CGLIB代理,如在
@EnableAspectJAutoProxy
注解中设置proxyTargetClass=true
,即使目标类实现了接口,Spring也会使用CGLIB代理。
总结
- JDK动态代理:适用于实现了接口的类,性能稍低。
- CGLIB代理:适用于没有接口的类,性能稍高,但不支持
final
类。
Coding不易,棒棒,加油!