首先,需要在 pom.xml 文件中添加 AOP 相关的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
为了标记需要记录操作日志的方法,我们可以定义一个 Log 注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String operation() default ""; // 操作内容
}
Log 注解中包含一个 operation 属性,用于记录操作内容。
接下来,我们需要定义一个 LogAspect 切面来实现操作日志的记录。LogAspect 切面需要使用 @Aspect 和 @Component 注解进行标记,表示它是一个切面并且可以被 Spring 管理。
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
/**
* 定义@Before增强,拦截带有@Log注解的方法,并记录操作日志
*/
@Before("@annotation(com.example.demo.aspect.Log)")
public void before(JoinPoint joinPoint) throws Exception {
// 获取目标方法名
String methodName = joinPoint.getSignature().getName();
// 获取目标方法参数
Object[] args = joinPoint.getArgs();
// 获取目标方法所在类
String className = joinPoint.getTarget().getClass().getName();
// 获取Log注解信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log logAnnotation = method.getAnnotation(Log.class);
// 记录操作日志 实际开发中这里可以改为插入数据库
logger.info("方法:{}.{}, 参数:{}, 操作:{}", className, methodName, Arrays.toString(args), logAnnotation.operation());
}
}
在 LogAspect 中,我们定义了一个 @Before 增强,用于拦截带有 @Log 注解的方法,并记录操作日志。在增强中,我们使用 JoinPoint 参数来获取目标方法的信息,包括方法名、参数和所在类。然后,我们通过反射来获取 Log 注解信息,从而实现日志记录。
最后,我们需要在需要记录操作日志的方法上使用 @Log 注解。例如:
@RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@Log("添加用户")
@PostMapping("/users")
public Result addUser(@RequestBody User user) {
logger.info("添加用户:{}", user);
userService.addUser(user);
return Result.success();
}
}
在本文中,我们介绍了如何使用SpringBoot和AOP来实现操作日志的记录。首先,我们了解了AOP的基本概念,然后介绍了如何定义切面和注解。最后,我们演示了如何使用注解来记录操作日志。
值得注意的是,在实际开发中,我们可能需要对操作日志进行更加详细的记录,例如记录操作者的信息、操作时间等。此时,我们可以通过扩展Log注解,添加更多的参数,从而实现更加灵活的日志记录。
该示例只展示了@Before增强,如果您想要获取方法的返回结果是否成功,将增强类型改为@AfterReturning,这样可以在方法正常返回后获取返回结果。在@AfterReturning增强中,可以使用JoinPoint和ReturningAdvice参数来获取方法的返回结果和相关信息。
以下是修改后的LogAspect类代码,包括获取方法返回结果是否成功的实现:
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
/**
* 定义@AfterReturning增强,拦截带有@Log注解的方法,并记录操作日志及返回结果
*/
@AfterReturning(value = "@annotation(com.example.demo.aspect.Log)", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) throws Exception {
// 获取目标方法名
String methodName = joinPoint.getSignature().getName();
// 获取目标方法参数
Object[] args = joinPoint.getArgs();
// 获取目标方法所在类
String className = joinPoint.getTarget().getClass().getName();
// 获取Log注解信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log logAnnotation = method.getAnnotation(Log.class);
// 获取方法返回结果是否成功
boolean isSuccess = true;
if (result != null && result instanceof Boolean) {
isSuccess = (boolean) result;
}
// 记录操作日志及返回结果
logger.info("方法:{}.{}, 参数:{}, 操作:{}, 返回结果:{}",
className, methodName, Arrays.toString(args), logAnnotation.operation(), isSuccess);
}
}