AOP 是什么?
面向切面编程
个人理解:我们一直说面向切面编程,这个面向切面编程到底是什么呢?
按照我的理解,程序执行是一段流程。从开始到结束,如同一条河流从源头流向大海。而AOP就是在这条河上建设堤坝,将其截断后进行自己想要进行的操作后再将其放行。比如三峡大坝,将河流截断后发电,两岸通行等等操作。
不同的是三峡大坝只拦截了一条河流,而AOP则可以将所有的河流全部拦截住。
原来在学的时候就感觉这么费劲干什么,不就是写一个方法,让这个方法在另一个方法的指定地方运行嘛。在真正接触项目后就感觉到这并不是简单的方法引用。同样的操作不用复写,甚至根本不用去想着这里需要进行这些操作,自然而然的就执行了。最常见的一个功能就是记录操作时间。将任何操作都记录下来,当出现问题的时候可以直接根据这些操作记录去追查原因。
比如我就写了一个记录API接口执行时间及请求IP的简单操作。
当然这个写的并不完全,操作人员还不能够记录。
实现AOP的操作需要引入的jar包
<!--SpringBoot中使用默认的redis的客户端-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
切面类
/**
* @program: fawukang
* @description: 请求拦截器
* @author: K.faWu
* @create: 2021-09-24 16:36
**/
@Aspect // 表示这是个切面类
@Component
@Slf4j
public class RequestInterceptor {
@Autowired
private LogRecordMapper logRecordMapper; //保存日志的dao层
/**
* 切入点: * com.kang.controller.*(..)
* 第一个*是指任何权限,任何返回值都可以执行
* 第二个* 指任何方法
* (..) 中的 .. 表示任意参数的方法
* @return
*/
//@Before("execution(* com.kang.controller.*(..))") 在方法之前执行 前置执行
// @After("execution(* com.kang.controller.*(..))") 在方法之后执行 后置执行
@Around("execution(* com.kang.controller.*.*(..))") // 环绕执行
public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
beforeController();
Signature signature = pjp.getSignature();
Object result;
try {
result = pjp.proceed();
}finally {
log.info("方法"+ signature.getName()+" 执行完毕");
}
return result;
}
/**
* 记录接口执行日志
*/
public void beforeController(){
ServletRequestAttributes sre = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); // 请求参数
HttpServletRequest request = sre.getRequest();
String ip = IpUtil.getIpAddr(request); // 发送请求的IP地址
String requestUrl = request.getRequestURL().toString();
String requestMethod = request.getMethod();
LogRecord logRecord = new LogRecord();
logRecord.setOperateIp(ip);
logRecord.setOperateUrl(requestMethod +":"+ requestUrl);
logRecord.setOperateTime(new Date());
logRecord.setOperateUser(request.getRemoteUser());
log.info(logRecord.toString());
logRecordMapper.insert(logRecord);
}
}
@Aspect // 表示这是个切面类
@Component
@Aspect 该注解表示这个类是个切面类用于Spring框架进行识别
@Component 组件注解,用于启动时的扫描加载