一、准备工作
- 准备一张日志表:主要包含字段有操作人,操作时间,操作类型,操作方法名,方法参数类型和值,返回值类型和值,操作时间等。。。
- 准备日志表的实体类,以及dao层,service层的编写
二、编写注解
自定义日志注解,作用在方法上,运行时启用
/**
* 自定义日志注解,作用在方法上,运行时启用
*/
@Inherited
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperateLog {
}
三、编写AOP处理逻辑
详情介绍体现在注释中
@Component
@Aspect
public class OperateAdvice {
//private static Logger log = Logger.getLogger(OperateAdvice.class);
@Autowired
private OperateAdviceMapper operateAdviceMapper;
// 扫描com.example.*.controller包下的任意类任意方法,参数也任意,且加了 @operateLog 注解的方法,通知类型为环绕类型
@Around("execution(* com.example.*.controller.*.*(..)) && @annotation(operateLog)")
public Object insertLogAround(ProceedingJoinPoint pjp , OperateLog operateLog) throws Throwable{
System.out.println(" *********************************** 记录日志 [start] ****************************** ");
// 创建日志类
OperationLog op = new OperationLog();
// 插入当前时间
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
op.setOperateTime(sdf.format(new Date()));
// 插入用户,从Session中获取当前登录用户(这里随机模拟)
op.setOperateUser("xiaoming");
// 插入类名
op.setOperateClass(pjp.getTarget().getClass().getName());
// 插入方法名
op.setOperateMethod(pjp.getSignature().getName());
// 插入参数
Object[] args = pjp.getArgs();
op.setParamAndValue(Arrays.toString(args));
long start_time = System.currentTimeMillis();
// 放行
Object object = pjp.proceed();
long end_time = System.currentTimeMillis();
// 插入执行耗时时间(结束时间 - 开始时间)
op.setCostTime(end_time - start_time);
// 插入返回值和类型
if(object != null){
op.setReturnClass(object.getClass().getName());
op.setReturnValue(object.toString());
}else{
op.setReturnClass("java.lang.Object");
op.setReturnValue("void");
}
//log.error(JsonUtils.obj2JsonString(op));
// 执行插入语句
operateAdviceMapper.insertOP(op);
System.out.println(" *********************************** 记录日志 [end] ****************************** ");
return object;
}
}
四、测试
1、将该注解加在一个学生类上
2、使用 ApiPost 工具来测试访问该借口
3、 查看日志表数据
已经成功加入日志