AOP学习
AOP介绍
- 如何在Spring中创建一个所谓切面?
@Aspect+@Component+通知+切点 - 切面里面的代码怎么运行在业务方法(之前、之后)?
通知+切点
使用
实现一个对service方法的增强,添加日志
- 添加依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
对业务方法添加计算时间的增强
- 业务类
java
@Service
public class UserService {
public void add(){
System.out.println("增加");
}
public void delete(){
System.out.println("删除");
}
public void update(){
System.out.println("修改");
}
public void query(){
System.out.println("查询");
}
}
- 切面类
啥叫面向切面编程:面向切面编程就是面向切面类进行编程
java
@Aspect //标记为切面类
@Component
public class LogAspect {
//实现方法用时 切点表达式
@Around("execution(* com.sping.service.UserService.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
//记录方法用时
long startTime = System.currentTimeMillis();
//执行具体的方法
try {
joinPoint.proceed(); //连接点就是具体的方法
}catch (Exception e){
System.out.println("方法执行异常");
throw new Exception();
}
long endTime = System.currentTimeMillis();
System.out.println("方法用时:" + (endTime - startTime) + "ms");
return null;
}
}
- 测试
java
@Autowired
private UserService userService;
@Test
public void test() throws InterruptedException {
userService.add();
}
@EnableAspectJAutoProxy
AOP的术语
切面、切点、通知、连接点;顾问(通知+切点)
通知
- 前置通知
- 后置通知
- 返回通知
- 异常通知
在定义切点的时候,可以把切点定义到另一个方法中,然后在通知中引入即可
java
@Aspect
@Component
public class LogAspect{
@Pointcut("execution( * com.sping.service.UserService.*(..))")
public void PointCut(){
}
@AfterReturning("PointCut()")
public void log(){
System.out.println("后置通知执行");
}
}
环绕通知和其他通知的区别:环绕通知需要手动去拿到连接点执行目标方法,环绕方法更加的灵活
前置通知@Before
在目标方法执行之前执行
java
@Aspect
@Component
public class LogAspect{
@Before("execution(* com.sping.service.*.*(..))")
public void log(){
System.out.println("前置通知执行");
}
}
可以看到标注了前置通知后,前置通知的增强方法先执行,然后再执行目标方法
后置通知@After
与前置通知相反,后置通知是目标方法执行之后才会执行,通知里的增强方法
java
@Aspect
@Component
public class LogAspect{
@After("execution(* com.sping.service.*.*(..))")
public void log(){
System.out.println("后置通知执行");
}
}
返回通知@AfterReturning
其实也是个后置通知,不过就是在方法返回后执行