面试官问:
说说什么是AOP?
AOP有哪些核心概念?
AOP有哪些环绕方式?
说说你平时都是怎么使用AOP的?
说说spring AOP和AspectJ AOP有什么区别?
说说JDK动态代理和CGLIB代理?
AOP,面向切面编程,旨在通过切面技术为业务主体增加额外的通知(Advice),从而对声明为“切点”(Pointcut)的代码快进行统一管理和装饰。
这种思想非常适用于将那些与核心业务不那么密切关联的功能添加到程序中。比如事务处理,缓存层,权限控制,资源同步,统一异常处理,性能统计。
AOP是对OOP的一种补充, OOP的核心单元是类,而AOP的核心单元是切面。利用AOP可以对业务逻辑的各个部分进行隔离,从而降低耦合度,提高程序的可用性,同时也提高了开发效率。
AOP的核心概念包括:
- 切面(Aspect):横切多个点的模块化。通常是一个类,用于封装遍布于应用各处的横切关注点。
- 连接点(Join Point):程序执行过程中的某个点,如方法调用、异常抛出等。
- 通知(Advice):切面在特定的连接点上执行的动作,如“around”、“before”和“after”等。
- 切入点(Pointcut):匹配连接点的断言。通知与切入点表达式关联,并在与切入点匹配的任何连接点上运行。
- 引入(Introduction):允许声明额外的方法或字段。
- 目标对象(Target Object):被一个或多个切面所通知的对象。
- AOP代理(AOP Proxy):AOP框架创建的对象,用于实现切面契约(包括通知方法执行等)。
- 织入(Weaving):将切面与其他应用类型或对象链接起来创建通知对象的过程。这可以在编译时、类加载时或运行时完成。
AOP的环绕方式:
- 前置通知(@Before):在连接点之前执行通知,但不能阻止执行流程继续到连接点。
- 后置返回通知(@AfterReturning):在连接点正常完成后执行通知。
- 后置异常通知(@AfterThrowing):如果方法抛出异常,则执行通知。
- 后置通知(@After):无论连接点退出的方式如何(正常或异常返回),都执行通知。
- 环绕通知(@Around):包围一个连接点的通知,如方法调用。这是最有力的通知类型,因为它可以在方法调用之前和之后自定义行为。
我平时使用AOP的方式:
- 记录日志:在方法执行前后记录信息,用于监控和调试。
- 权限验证:在方法执行前检查用户是否有权限执行该操作。
- 事务管理:在方法执行前后管理事务的开启和提交/回滚。
- 性能监控:在方法执行前后记录时间,用于监控方法性能。
- 缓存:在方法执行前检查缓存,避免重复计算。
Spring AOP和AspectJ AOP的区别:
-
Spring AOP:
- 运行时增强:基于代理模式(默认使用JDK动态代理,也可以使用CGLIB)。
- 只能作用于Spring管理的Bean。
- 通常用于轻量级的应用场景。
-
AspectJ:
- 编译时增强、加载时织入或运行时织入:更强大,可以直接修改字节码。
- 可以作用于任何Java对象,不仅限于Spring管理的Bean。
- 适用于更复杂的切面需求。
JDK动态代理和CGLIB代理:
-
JDK动态代理:
- 基于接口:目标对象必须实现一个或多个接口。
- 使用Java反射机制动态创建代理类和对象。
- 性能相对较低。
-
CGLIB代理:
- 基于继承:通过创建目标类的子类来生成代理对象。
- 目标类无需实现接口。
- 通常比JDK动态代理性能更好,但创建代理对象的过程更复杂。