AOP概述
· AOP:Aspect Oriented Programming(面向切面编程、面相方法编程),其实就是面向特定方法编程,即在方法(或类)运行之前或之后,我们可以使用AOP将一些额外操作切入至其指定位置上(一般切入到某些方法上)。其底层是使用动态代理机制实现的。
· 例如,案例某部分运行较慢,若要定位出执行耗时较长的业务方法,需要统计每一个业务方法的执行耗时。此时就可以使用AOP便捷的进行统计。
另外记录操作日志、权限控制、事务管理等场景都会用到AOP,使用不可谓不广泛!
快速入门
· 首先导入AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
· 编写AOP方法
首先我们定义一个AOP增强操作的类,添加@Aspect
注解声明为AOP类,添加@Component
将其注册为Bean。
@Aspect //AOP类
@Component
public class TimeAspect {
}
如果切入的方法有参数传递,我们可以为其添加ProceedingJoinPoint 参数来获取切入点信息。(如果是其它类型通知则参数类型为JoinPoint)
System.out.println("参数列表:"+ Arrays.toString(point.getArgs()));
切入点表达式中第一个*是方法的返回值类型,第二个*是类名,第三个*是方法名。通配符*代表无限制全部包含,当然你也可以具体指定。
我这里选择使用Slf4j打印日志的方式输出耗时,当然为了方便也可直接sout打印在控制台。
@Aspect //AOP类
@Component
@Slf4j
public class TimeAspect {
@Around("execution(* com.book.service.Imp.*.*)") //切入点表达式
public Object Time(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed(); //调用原始方法
long end = System.currentTimeMillis();
log.info("方法耗时: {} ms", end - start);
return result;
}
}
我们来测试一下com.book.service.Imp包下的一个类,当然为了方便你也可以直接写一个for循环进行测试。
@Component
public class BorrowServiceImp implements BorrowService {
@Resource
BorrowMapper borrowMapper;
@Override
public List<Borrow> getBorrowList() {
return borrowMapper.getBorrowList();
}
}
可以看到日志成功打印了方法耗时。
INFO 11048 --- [nio-8080-exec-1] com.book.aop.TimeAspect : 方法耗时: 90 ms
除了@Around,还有很多可以直接使用的注解,比如@before、@AfterReturning、@AfterThrowing等。(我们实现的AOP方法即为通知)