1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.SQL的表结构
CREATE TABLE `operate_log` (
`id` varchar(32) NOT NULL,
`create_time` datetime DEFAULT NULL COMMENT '调用时间',
`type` varchar(20) DEFAULT NULL COMMENT '接口类型',
`request_value` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '请求值',
`return_value` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '返回值',
`caller` varchar(32) DEFAULT NULL COMMENT '调用者',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述',
`tenant_id` varchar(32) DEFAULT NULL COMMENT '租户id',
`branch_code` varchar(32) DEFAULT NULL COMMENT '车间编码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='操作日志';
3.依次写入entity,dao,service
@TableName(value ="operate_log")
public class OperateLog implements Serializable {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private Date createTime;
private String type;
private String requestValue;
private String returnValue;
private String caller;
private String description;
private String tenantId;
private String branchCode;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
public OperateLog() {}
public OperateLog(String desc, String result,String caller, String value,String type) {
this.id = UUID.randomUUID().toString().replaceAll("-", "");
this.createTime = new Date();
this.description = desc;
this.caller = caller;
this.returnValue = result;
this.requestValue = String.valueOf(value);
this.type = type;
}
public interface OperateLogMapper extends BaseMapper<OperateLog> {
}
public interface OperateLogService extends IService<OperateLog> {
}
@Service
public class OperateLogServiceImpl extends ServiceImpl<OperateLogMapper, OperateLog>
implements OperateLogService {
}
4.定义切面,并实现自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String desc() default "";
String caller() default "";
}
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private OperateLogService operateLogService;
@Pointcut("@annotation(OperationLog)")
public void logsPoinCut() {
}
@Around(value = "logsPoinCut()")
public Object saveLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object proceed = proceedingJoinPoint.proceed();
try {
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
OperationLog annotation = methodSignature.getMethod().getAnnotation(OperationLog.class);
String type = annotation.desc();
String caller = annotation.caller();
Result result = (Result) proceed;
String returnValue =String.valueOf(result.getMsg());
String desc = String.valueOf(result.getData());
Map<String, Object> map = new HashMap<String, Object>(5);
Object[] values = proceedingJoinPoint.getArgs();
String[] names = ((CodeSignature) proceedingJoinPoint.getSignature()).getParameterNames();
for (int i = 0; i < names.length; i++) {
map.put(names[i], values[i]);
}
String value = String.valueOf(map);
OperateLog operateLog = new OperateLog(desc, returnValue, caller, value, type);
operateLogService.save(operateLog);
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return proceed;
}
5.在controller层添加自定义注解,实现代码无侵入,满足开闭原则
@OperationLog(desc = "login" , caller = "admin")
@PostMapping("/login")
public Result<User> userLogin(@RequestBody User userParam) {
if (userParam == null) {
return Result.error("-1", "用户未输入值");
}
User user = userService.userLogin(userParam.getUsername(), userParam.getPassword());
if (user == null) {
return Result.error("-1", "用户名或密码错误");
}
return Result.success(user);
}
结果展示