前言
AOP(面向切面编程 Aspect-Oriented Programming)是一种编程范式,旨在提高代码模块化,通过将跨多个点的功能(如日志、安全性、事务管理等)集中处理,来达到解耦合和减少代码冗余的目的。
比喻
AOP:Aspect Oriented Programming 的缩写,意为:面向切面编程。
面向切面编程的目标就是分离关注点。什么是关注点呢?就是关注点,就是你要做的事情。假如你是一位公子哥,没啥人生目标,每天衣来伸手,饭来张口,整天只知道一件事:玩(这就是你的关注点,你只要做这一件事)!但是有个问题,你在玩之前,你还需要起床、穿衣服、穿鞋子、叠被子、做早饭等等等等,但是这些事情你不想关注,也不用关注,你只想想玩,那么怎么办呢?
对!这些事情通通交给下人去干。你有一个专门的仆人 A 帮你穿衣服,仆人 B 帮你穿鞋子,仆人 C 帮你叠好被子,仆人 D 帮你做饭,然后你就开始吃饭、去玩(这就是你一天的正事),你干完你的正事之后,回来,然后一系列仆人又开始帮你干这个干那个,然后一天就结束了!
这就是 AOP。AOP 的好处就是你只需要干你的正事,其它事情别人帮你干。也许有一天,你想裸奔,不想穿衣服,那么你把仆人 A 解雇就是了!也许有一天,出门之前你还想带点钱,那么你再雇一个仆人 E 专门帮你干取钱的活!这就是AOP。每个人各司其职,灵活组合,达到一种可配置的、可插拔的程序结构。
核心概念:
- 切面(Aspect):切面是跨应用程序多处分散的关注点(例如日志记录、事务管理等),可以被模块化到特殊的类中。
- 连接点(Join Point):程序执行过程中的某个特定点,如方法调用或异常的抛出。在AOP术语中,连接点总是表示方法的执行。
- 通知(Advice):在切面的一个“建议”或动作,它在特定的连接点(Join Point)被执行。通知的类型有:前置通知(Before)、后置通知(After)、返回后通知(After-returning)、抛出异常时通知(After-throwing)和环绕通知(Around)。
- 切点(Pointcut):匹配连接点(Join Points)的表达式。简单地说,它告诉AOP框架在哪里应用通知(即在哪些方法执行时,哪些类上)。
- 引入(Introduction):向现有的类添加新方法或属性的能力。
- 目标对象(Target Object):被一个或多个切面增强的对象。
工作原理:
AOP 工作的核心在于代理模式。AOP框架在运行时动态地在目标对象的方法前后(或在其他连接点)插入增强逻辑(由相应的通知定义),从而生成目标对象的代理对象。这样做的好处是可以在不修改源代码的情况下,为业务逻辑增加额外的处理。
应用场景:
- 日志记录:记录方法的执行时间,参数,返回值等。 - 事务管理:对数据库操作方法进行事务管理。 - 权限检查:在方法执行前检查用户是否具有权限。 - 性能统计:统计方法执行时间以监控性能。 - 异常处理:对方法执行中的异常进行统一处理。
示例:
以 Spring AOP 为例,以下是一个关于如何应用“前置通知”来记录方法执行信息的例子:
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("即将执行方法:" + joinPoint.getSignature().getName());
}
}
在上面的示例中,@Aspect
注解标记这个类是一个切面,@Before
注解表示这个方法是一个前置通知,它将在目标对象的方法执行前执行。execution(* com.example.service.*.*(..))
是切点表达式,指示这个通知应用于 com.example.service
包下所有类的所有方法。
总结:
AOP 提供了一种强大的方式来解耦软件组件,将横切关注点(如日志、事务、安全等)集中管理,有助于提高代码的重用性和维护性。