📅  最后修改于: 2023-12-03 14:47:32.553000             🧑  作者: Mango
AOP(Aspect-Oriented Programming)面向切面编程,是一种面向对象编程的补充。 在AOP中,通过预编译方式和运行期动态代理实现程序功能的统一维护的技术。AOP 主要关注业务横向的方向,可用于权限控制、日志处理、性能统计、事务处理、异常处理等场景。
Spring Boot整合了AOP框架,可以通过使用注解或XML文件来实现AOP功能。Spring AOP默认使用JDK动态代理,如果被代理的类实现了接口,则使用JDK动态代理;如果被代理的类没有实现接口,则使用CGLIB动态代理。
围绕建议是Spring AOP中的一种类型,通过在被拦截的方法前后添加处理逻辑来实现围绕建议。围绕建议可以在方法执行前后添加处理逻辑,并且可以在方法抛出异常时执行处理逻辑。Spring Boot支持使用@Aspect注解来实现围绕建议。
环绕通知通过ProceedingJoinPoint对象来控制方法执行。环绕的方法必须有ProceedingJoinPoint对象作为参数,并且必须调用proceed()方法来继续执行接下来的方法逻辑。环绕通知常用于日志、性能监控等。
@Aspect
@Component
public class LogAspect {
@Around("execution(* com.example.springboot.controller..*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
System.out.println("[Aspect]方法" + joinPoint.getTarget().getClass().getName()
+ "." + joinPoint.getSignature().getName() + "耗时" + (endTime - startTime) + "ms");
return result;
}
}
前置通知通过@Before注解来实现,在被拦截的方法执行之前执行。前置通知常用于权限控制、参数校验等。
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.springboot.controller..*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("[Aspect]方法" + joinPoint.getTarget().getClass().getName()
+ "." + joinPoint.getSignature().getName() + "开始执行");
}
}
后置通知通过@After注解来实现,在被拦截的方法执行之后执行。后置通知常用于记录日志、释放资源等。
@Aspect
@Component
public class LogAspect {
@After("execution(* com.example.springboot.controller..*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("[Aspect]方法" + joinPoint.getTarget().getClass().getName()
+ "." + joinPoint.getSignature().getName() + "执行结束");
}
}
返回通知通过@AfterReturning注解来实现,在被拦截的方法返回结果后执行。返回通知常用于记录日志、处理返回结果等。
@Aspect
@Component
public class LogAspect {
@AfterReturning(pointcut = "execution(* com.example.springboot.controller..*.*(..))", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("[Aspect]方法" + joinPoint.getTarget().getClass().getName()
+ "." + joinPoint.getSignature().getName() + "返回结果:" + result);
}
}
异常通知通过@AfterThrowing注解来实现,在被拦截的方法抛出异常后执行。异常通知常用于记录异常日志、发送告警邮件等。
@Aspect
@Component
public class LogAspect {
@AfterThrowing(pointcut = "execution(* com.example.springboot.controller..*.*(..))", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Exception e) {
System.out.println("[Aspect]方法" + joinPoint.getTarget().getClass().getName()
+ "." + joinPoint.getSignature().getName() + "抛出异常:" + e.getMessage());
}
}
通过对AOP的介绍以及Spring Boot中的实现机制,我们可以了解到围绕建议是AOP中的一种重要实现方式。通过围绕建议,我们可以在方法执行前后添加处理逻辑,实现日志记录、性能监控、权限控制等常见场景。在实现围绕建议时,需要注意执行顺序以及参数类型等问题,避免对业务功能造成影响。