目录
1.引入依赖
2.创建增强类
3.写我们的被增强类
4.运行我们的程序,访问 /aoptest
5.应用场景
AOP 概念:
- 切入点 pointcut
- 通知 advice
- 切面 aspect = 切入点 + 通知
- 织入 weaving 将切面加入对象,并创建出代理对象的过程
- 环绕通知 【最强大、灵活的通知】
org.springframework.boot spring-boot-starter-aop
execution 表达式相关文章:AOP(execution表达式)
package com.example.demo.aop;import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;/*** @author: fly* @Date: 2023-03-19 14:50* @Description: 切面类*/
@Aspect
@Component
@Log4j2
public class AopLog {// 线程局部的变量,用于解决多线程中相同变量的访问冲突问题ThreadLocal startTime = new ThreadLocal<>();// 定义切点 com.example.demo 下面的当前包和子包下面的所有类中的所有方法// @Pointcut("execution(* com.example.demo..*.*(..))")// 针对 controller 层的 AopLog 类的 aopTest方法进行测试@Pointcut("execution(String com.example.demo.controller.AopLogController.aopTest())")public void aopWebLog() {}// 前置通知@Before("aopWebLog()")public void doBefore(JoinPoint joinPoint) {// 记录开始时间startTime.set(System.currentTimeMillis());// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();assert attributes != null;HttpServletRequest request = attributes.getRequest();log.info("URL: " + request.getRequestURL().toString());log.info("HTTP方法: " + request.getMethod());log.info("IP地址: " + request.getRemoteAddr());log.info("类的方法: " + joinPoint.getSignature().getDeclaringTypeName() + "." +joinPoint.getSignature().getName());log.info("参数: " + request.getQueryString());}// 方法抛出异常退出时执行的通知@AfterThrowing(pointcut = "aopWebLog()",throwing = "exception")public void addAfterThrowingLog(JoinPoint joinPoint,Exception exception) {log.error("执行 " + "异常",exception);}
}
拓展知识:通知的分类
- @Before 前置通知
- @AfterReturning 后置通知
- @After 最终通知
- @AfterThrowing 异常通知
- @Around 环绕通知 【与上面的通知的写法稍微有点区别】
public void around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("[增强类]环绕通知前...");pjp.proceed();System.out.println("[增强类]环绕通知后..."); }
根据切入点,我们可以定位到 被增强类
@Pointcut("execution(String com.example.demo.controller.AopLogController.aopTest())")
@RestController
public class AopLogController {@RequestMapping("/aoptest")public String aopTest() {return "hello aop test!";}
}
拓展资料: