概述
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方
式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
aop是面向切面编程,在spring中用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般比如可以做为公共日志保存,事务处理等
比如我们在进行某一个网站设计的时候,有一个业务模块需要记录操作者进行的操作操作者进行信息的修改的时候,需要进行日志记录(xxx在xxx时间进行了xxx信息的修改),增删查改的时候都需要记录,很明显这部分对于一个“摸鱼”仔来讲,是不能容忍的,意味着我要在每一个业务操作的时候,都需要写这一部分代码。
spring中应用
日志记录
AOP 可以用于记录方法的输入、输出、异常等信息,实现统一的日志记录,而无需在每个方法中都添加日志记录代码。
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBeforeMethodExecution(JoinPoint joinPoint) {
System.out.println("Method " + joinPoint.getSignature().getName() + " is about to be executed.");
}
}
事务管理
AOP 可用于实现事务管理,确保在一系列相关操作中,要么全部成功执行,要么全部回滚。
@Service
public class TransactionalService {
@Transactional
public void performTransactionalOperation() {
// 事务管理的业务逻辑
}
}
知识点补充
核心概念
Join point
:连接点,表示程序执行期间的一个点,在 Spring AOP 表示的就是一个方法,即一个方法可以看作是一个 Join pointpointcut
:切点,就是与连接点匹配的谓词,什么意思呢,就是需要执行 Advice 的连接点就是切点Advice
:增强,在连接点执行的操作,分为前置、后置、异常、最终、环绕增强五种Aspect
:切面,由 pointcut 和 Advice 组成,可以简单的认为 @Aspect 注解的类就是一个切面Target object
:目标对象,即 织入 advice 的目标对象AOP proxy
:代理类,在 Spring AOP 中, 一个 AOP 代理是一个 JDK 动态代理对象或 CGLIB 代理对象- `Weaving` :织入,将 Aspect 应用到目标对象中去
常用注解
-
@Aspect
:用于标记一个类为切面类。 -
切点表达式相关注解:
@Pointcut
:定义一个切点,表示哪些方法需要被织入。
-
通知类型相关注解:
@Before
:在方法执行前执行通知。@After
:在方法执行后执行通知。@AfterReturning
:在方法返回结果后执行通知。@AfterThrowing
:在方法抛出异常后执行通知。@Around
:在方法执行前后都执行通知。
-
引入类型相关注解:
@DeclareParents
:引入新的接口和实现类,使得目标类也具有该接口的特性。
-
其他注解:
@Order
:指定切面的优先级顺序,数值越小优先级越高。@EnableAspectJAutoProxy
:启用自动代理。
切点表达式
根据表达式描述匹配方法,是最通用的表达式类型,可以匹配方法、类、包。
表达式模式:
execution(modifier? ret-type declaring-type?name-pattern(param-pattern) throws-pattern?)
表达式解释:
- modifier:匹配修饰符,
public, private
等,省略时匹配任意修饰符 - ret-type:匹配返回类型,使用
*
匹配任意类型 - declaring-type:匹配目标类,省略时匹配任意类型
-
..
匹配包及其子包的所有类
- name-pattern:匹配方法名称,使用
*
表示通配符
-
*
匹配任意方法set*
匹配名称以set
开头的方法
- param-pattern:匹配参数类型和数量
-
()
匹配没有参数的方法(..)
匹配有任意数量参数的方法(*)
匹配有一个任意类型参数的方法(*,String)
匹配有两个参数的方法,并且第一个为任意类型,第二个为String
类型
- throws-pattern:匹配抛出异常类型,省略时匹配任意类型