【Spring 使用】AOP 的介绍及使用例子
文章目录
一. AOP 相关内容介绍
Spring AOP 是一个面向切面的编程框架,是 Spring 对 OOP 的一种补充,在讲解 Spring 容器的过程中,会提到容器是生产和管理 Bean 的重要的核心,不仅仅是生产 Bean,还可以在 Bean 生成和销毁的前后进行各种自定义操作。
而AOP 就是对整个管理的 Bean 进行切割,以便在 Bean 中方法的前后进行自定义处理。
引用一张图就是:
1. 术语
AOP 的术语有下面几个:
- 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
- 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
- 切点(PointCut): 可以插入增强处理的连接点。
- 切面(Aspect): 切面是通知和切点的结合。
- 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
- 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
2. 通知(Advice)的类型
-
前置通知(Before Advice)
前置通知是在连接点前进行执行的通知,在 xml 中可以使用<aop:before>
或者使用注解@Before
进行表示。 -
后置通知(After Advice)
后置通知是在连接点后进行执行的通知,当返回和异常都可以进行处理,在 xml 中可以使用<aop:after>
或者使用注解@After
进行表示。 -
返回后通知(After Return Advice)
只有当连接点正常返回正常执行完才会执行,如果出现异常则不会执行,在 xml 中可以使用<aop:after-returning>
或者使用注解@AfterReturning
进行表示。 -
环绕通知(Around Advice)
环绕通知相当于前置和后置的结合体,只不过两者可以同时使用,如果抛出了异常,则环绕通知只有前一步,而没有后一步通知,在 xml 中可以使用<aop:around>
或者使用注解@Around
进行表示。 -
异常通知(After Throwing Advice)
异常通知就是在连接点的执行过程中如果出现了异常,则会执行的通知,在 xml 中可以使用<aop:after-throwing>
或者使用注解@AfterThrowing
进行表示。
使用一张表进行归纳:
通知 | 英文 | XML使用 | 注解使用 |
---|---|---|---|
前置通知 | Before Advice | aop:before | @Before |
后置通知 | After Advice | aop:after | @After |
返回后通知 | After Return Advice | aop:after-returning | @AfterReturning |
环绕通知 | Around Advice | aop:around | @Around |
异常通知 | After Throwing Advice | aop:after-throwing | @AfterThrowing |
3. 切入点表达式的规则
【1】规则
通常情况下使用 execution 表达式就能解决大部分问题,execution 的表达式规则如下:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
其中每个参数的意义:
- modifiers-pattern:操作权限,比如 public、private,可以省略
- ret-type-pattern:返回值类型,通常使用星号
- declaring-type-pattern:方法所在的包,比如 com.test
- name-pattern:方法名
- param-pattern:参数名
- throws-pattern:异常
【2】例子
以下面的例子中的表达式来解释上面的规则:
execution(* com.test.MyBean.*(..))
符号 | 含义 |
---|---|
execution() | execution 表达式主体 |
第一个 * | 任意返回值 |
com.test | 当前所在的包名 |
MyBean | 切面所在的类名 |
第二个 * | 表示当前类中任意方法都可以进行通知 |
(…) | 表示方法可以是任意参数类型 |
二. 基于 XML 方式的使用
在 XML 文件中注册并使用是 Spring 最基本的方式。使用的时候需要注意:
- 在使用环绕通知的时候,一定要在参数中添加 ProceedingJoinPoint 类型的参数。
- 如果需要使用异常通知,则需要指定捕获的异常名称是什么。
- 目录结构:
|-- src.main
|-- java.com.test
|-- Main.java
|-- MyBean.java
|-- MyAspectJ.java
|-- resources
|-- MyBean.xml
- MyAspectJ.java:
public class MyAspectJ {
public void before() {
System.out.println("前置通知:before Advice...");
}
public void after() {
System.out.println("后置通知:after Advice...");
}
public void around(ProceedingJoinPoint joinPoint) {
try {
System.out.println("环绕前通知:around Advice...");
joinPoint.proceed();
System.out.println("环绕后通知:around Advice...");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
public void afterReturning() {
System.out.println("返回后通知:afterReturning Advice...");
}
public void afterThrowing(JoinPoint joinPoint, Exception exception) {
System.out.println("异常通知:afterThrowing Advice...\n"
+ ",切入点:" + joinPoint + "\n"
+ ",异常:" + exception.getMessage());
}
}
- MyBean.java:
public class MyBean {
private String mes