[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| Aspect | n. | /ˈæspekt/ | 切面(Spring AOP核心概念,封装横切关注点(如日志、事务)的模块,由切点(Pointcut)和通知(Advice)组成,用于定义“在何时、何处执行增强逻辑”) |
| Before | prep. / adj. | /bɪˈfɔː(r)/ | 之前(AOP中的前置通知,用@Before注解标识,指在目标方法执行之前触发的增强逻辑,如参数校验、日志记录开始) |
| After | prep. / adj. | /ˈɑːftə(r)/ | 之后(AOP中的后置通知,用@After注解标识,指在目标方法执行之后(无论是否抛出异常)触发的增强逻辑,如资源释放) |
| Returning | v. (现在分词) | /rɪˈtɜːnɪŋ/ | 返回(AOP中的返回通知,用@AfterReturning注解标识,指在目标方法正常返回后触发的增强逻辑,可获取返回值,如结果日志) |
| Throwing | v. (现在分词) | /ˈθrəʊɪŋ/ | 抛出(AOP中的异常通知,用@AfterThrowing注解标识,指在目标方法抛出异常后触发的增强逻辑,可捕获异常信息,如错误处理) |
| execution | n. | /ˌeksɪˈkjuːʃn/ | 执行(AOP中用于定义切点的表达式关键字,通过execution()指定需要增强的目标方法,如execution(* com.example.service.*.*(..))匹配服务层所有方法) |
Lecture12-切面-[实验01]初步实现
1、加入依赖
在 IoC 测试工程环境的基础上,额外再增加下面依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、准备被代理的目标资源
①接口
public interface Calculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
②纯净的实现类
在 Spring 下工作,所有的一切都必须放在 IoC 容器中。现在接口的实现类是 AOP 要代理的目标类,所以它也必须放入 IOC 容器。
package com.atguigu.aop.impl;
import com.atguigu.aop.api.Calculator;
import org.springframework.stereotype.Component;
@Component
public class CalculatorPureImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
System.out.println("方法内部 result = " + result);
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
System.out.println("方法内部 result = " + result);
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
System.out.println("方法内部 result = " + result);
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
System.out.println("方法内部 result = " + result);
return result;
}
}
3、创建切面类
// @Aspect表示这个类是一个切面类
@Aspect
// @Component注解保证这个切面类能够放入IOC容器
@Component
public class LogAspect {
// @Before注解:声明当前方法是前置通知方法
// value属性:指定切入点表达式,由切入点表达式控制当前通知方法要作用在哪一个目标方法上
@Before(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")
public void printLogBeforeCore() {
System.out.println("[AOP前置通知] 方法开始了");
}
@AfterReturning(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")
public void printLogAfterSuccess() {
System.out.println("[AOP返回通知] 方法成功返回了");
}
@AfterThrowing(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")
public void printLogAfterException() {
System.out.println("[AOP异常通知] 方法抛异常了");
}
@After(value = "execution(public int com.atguigu.aop.api.Calculator.add(int,int))")
public void printLogFinallyEnd() {
System.out.println("[AOP后置通知] 方法最终结束了");
}
}
4、测试
@SpringBootTest
public class AOPTest {
@Autowired
private Calculator calculator;
@Test
public void testAnnotationAOP() {
int add = calculator.add(10, 2);
System.out.println("方法外部 add = " + add);
}
}
打印效果如下:
[AOP前置通知] 方法开始了 方法内部 result = 12 [AOP返回通知] 方法成功返回了 [AOP后置通知] 方法最终结束了 方法外部 add = 12