Spring AOP编程
1. 什么是面向切面编程(AOP)
-
AOP是一种编程思想,它将程序的业务逻辑和系统服务分离开来,通过对横切关注点的分离,它可以使得业务逻辑和系统服务更加清晰,降低了模块间的耦合度,提高了系统的可重用性,同时提高了开发的效率。
-
在软件开发中,散布于应用中多处的功能被称为横切关注点(比如日志、安全和事务管理)。通常来讲,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往会直接嵌入到应用的业务逻辑之中)。把这些横切关注点与业务逻辑相分离正是面向切面编程(AOP)所要解决的问题。
-
简而言之,横切关注点可以被描述为影响应用多处的功能,AOP能帮助我们模块化横切关注点(切面)。在使用面向切面编程时,我们仍然在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的业务逻辑类。
2. 面向切面编程的好处:
每个横切关注点都集中于一个地方,而不是分散到多处代码中。 服务模块更简洁,因为它们只包含业务逻辑的代码,而横切关注点的代码被转移到一个统一的地方了。
AOP术语
-
横切关注点 跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志、安全、缓存、事务等等。
-
连接点 连接点是在应用执行中能够插入切面的一个点。即程序执行过程中能够应用通知的所有点。
-
切点 切点是真正需要插入切面的一个或多个连接点。即通知被应用的具体位置。 通常使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点(比如Aspect切点表达式)。
-
通知 切面的工作被称为通知。通知是在特定的连接点上执行的,它是一种在程序执行期间插入切面的方法。通知的类型有:前置通知、后置通知、异常通知、最终通知、环绕通知。
- 切面
- 织入
- 引用
通知的类型
- 前置通知(Before):在目标方法被调用之前调用通知功能。
- 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么。
- 返回通知(After-returning):在目标方法成功执行之后调用通知。
- 异常通知(After-throwing):在目标方法抛出异常后调用通知。
- 环绕通知(Around) :通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
3. Spring AOP的实现
这是一个具体通知类的实现,它包含了一个通知方法,该方法将在切点执行时被调用。
@Aspect
public class Audience {
// performance()方法的实际内容并不重要,它只是一个标识,供@Pointcut注解依附
@Pointcut("execution(* concert.Performance.perform(..))") // 定义命名的切点
public void performance() {
}
@Before("performance()") // 前置通知
public void silenceCellPhones() {
System.out.println("Silencing cell phones");
}
@Before("performance()") // 前置通知
public void takeSeats() {
System.out.println("Taking seats");
}
@AfterReturning("performance()") // 返回通知
public void applause() {
System.out.println("CLAP CLAP CLAP!!!");
}
@AfterThrowing("performance()") // 异常通知
public void demandRefund() {
System.out.println("Demanding a refund");
}
}
环绕通知
@Around("performance()")
public Object watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Silencing cell phones");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable e) {
System.out.println("Demanding a refund");
}
return null;
}