Spring 面试题, Spring AOP默认用的是什么动态代理,两者的区别?
Spring 面试题, Spring AOP默认用的是什么动态代理,两者的区别?
QA
Step 1
Q:: Spring AOP默认用的是什么动态代理?
A:: Spring AOP 默认使用的是 JDK 动态代理和 CGLIB 动态代理。如果目标类实现了接口,Spring 默认使用 JDK 动态代理;如果目标类没有实现任何接口,Spring 会选择使用 CGLIB 动态代理。JDK 动态代理通过实现接口来创建代理对象,而 CGLIB 通过生成目标类的子类来创建代理对象。
Step 2
Q:: JDK 动态代理和 CGLIB 动态代理的区别是什么?
A:: JDK 动态代理只能代理实现了接口的类,而 CGLIB 代理可以代理没有实现接口的类。JDK 动态代理在运行时通过反射机制生成代理类,而 CGLIB 则是在运行时生成目标类的子类并重写方法。因此,CGLIB 代理会稍微复杂一些,并且代理类的性能也比 JDK 动态代理稍差。此外,CGLIB 代理无法代理 final 类或 final 方法,因为它依赖于生成子类。
Step 3
Q:: 如何选择使用 JDK 动态代理还是 CGLIB 代理?
A:: 如果目标类实现了接口,Spring AOP 默认使用 JDK 动态代理,这通常也是最好的选择,因为它更简单且性能较好。如果目标类没有实现接口,Spring 会自动切换到 CGLIB 动态代理。你也可以通过配置强制使用 CGLIB 动态代理,例如在 Spring 配置中设置 proxyTargetClass=true
。在实际项目中,应该根据类是否实现接口、性能需求和是否需要代理 final 类或方法来选择合适的代理方式。
Step 4
Q:: Spring AOP 是如何工作的?
A:: Spring AOP 是通过代理模式来实现的。当对目标对象的方法调用进行拦截时,AOP 框架会在调用目标方法之前和之后执行一些额外的逻辑,这些逻辑通常被称为“切面”。Spring AOP 的实现基于切点(Pointcut)和通知(Advice)。切点定义了在哪些方法上应用通知,通知则定义了在这些方法的哪个阶段(例如,方法执行前、方法执行后、抛出异常后)执行额外的逻辑。
Step 5
Q:: Spring AOP 和 AspectJ 有什么区别?
A:: Spring AOP 是基于代理的 AOP 实现,支持方法级别的切面,比较轻量级,适合用在常规的 Spring 项目中。AspectJ 是功能更强大的 AOP 框架,它是编译时增强(或加载时增强),不仅支持方法级别的切面,还支持构造函数、字段的拦截。AspectJ 提供了更强大的功能,但复杂度也更高,通常用于对性能要求较高或需要更精细的切面控制的场景。