概述
同前面 SpringSecurity 的学习记录博文一样,在此次项目之中就有这样一个需求,于是我第一时间想到利用 AOP 去解决这件事。
那么我们可以回顾一下 AOP 是什么。它指的是「面向切面」是 Spring 之中的一个很强大的特性,并且在 Spring 的很多东西都是由此为基础去实现的,比如我们经常用到的「拦截器」。简单的来说,就是我们想去实现一些功能,但又不想改变代码原有的结构,比如我们想在某个 controller 的接口结束之后自动做某些操作啦,或在其执行之前做什么操作。
这些都可以依靠 AOP 进行实现。
实现
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
代码
首先,我们的需求是某些操作执行完毕之后去记录一下,那么我们必然需要知道它是干什么的,我们该如何得知呢?如果是前面所学的 before 或 after 似乎都无法实现这样一个需求。
所以我们想我们可以去实现一个注解,然后使用注解去标注其值,我们只需要获取到注解之内的值就可以了~
注解
于是我创建了一个名为「OperLog」的注解。主要在方法之上使用,并且拥有三个参数来进行阐述该功能的信息。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperLog {
String operModul() default ""; // 操作模块
String operType() default ""; // 操作类型
String operDesc() default ""; // 操作说明
}
其后,我们可以直接使用它在某些模块上进行展示。见下面代码。
@PostMapping("/xxxx/xxx")
@ResponseResult
@OperLog(operModul = "设置模块",operType = "常规配置修改",operDesc = "后台修改常规配置")
public void setxxxxxConfig(@RequestBody JSONObject jsonObject) {
切面类
然后我们需要创建一个名为「OperLogAspect」的切面类。需要加上注解「@Aspect」声明其是切面类,然后将其注册为组件。
@Aspect
@Component
public class OperLogAspect {
之后我们通过注解来实现一个切入点。
@Pointcut("@annotation(com.xxx.annotations.OperLog)")
public void operLogPoinCut() {
}
然后使用这个切入点。使用「joinPoint」参数获取对应的方法,然后通过方法获取我们的注解,再通过注解去获得我们上述在模块之上记录的模块相关的信息,然后使用自己定义的「logService」将其存入 Redis 之中。
「@AfterReturning」注解实际上还可以获取对应方法的返回值,不过我们并没有用到,只是为了学习所以才这样使用。
@AfterReturning(value = "operLogPoinCut()", returning="returnValue")
public void saveOperLog(JoinPoint joinPoint, Object returnValue) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
OperLog opLog = method.getAnnotation(OperLog.class);
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
String Authorization = request.getHeader("Authorization");
String username = JwtUtils.getUsername(Authorization);
JSONObject jsonObject = new JSONObject();
jsonObject.put("operModul", opLog.operModul());
jsonObject.put("operType", opLog.operType());
jsonObject.put("operDesc", opLog.operDesc());
jsonObject.put("userName", username);
jsonObject.put("date", new Date());
logService.addLog(jsonObject);
}
本页的评论功能已关闭