说明:本文只是对日志操作的简单Demo
1.自定义注解
public enum LogEnum {
ADD,EDIT,DEL,QUERY;
}
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
//@Documented //生成文档
public @interface AnnotationForLog {
LogEnum operationType() default LogEnum.QUERY; //操作
String operation();//大白话描述
String operationalEntity();//操作对象
}
2.日志实体-对应数据表
@Setter
@Getter
@TableName("LRP_LOG_SYS")
public class LrpLogSys implements Serializable {
@TableId(type = IdType.UUID)
private String id;
private String insertUser;
private Date insertDate;
private String description;//描述json格式
private String operation;//简短描述,文字描述
private String operationType;//操作类型 ADD DEL EDIT QUERY
private String operationalEntity;//操作实体,例如:Student.java
private String successOrNot;是否成功 0失败 1成功
private String whyError;//失败原因
private String sysName = "LRP";//系统名称
}
3.AOP环绕通知
@Aspect
@Component
public class SysLogAspect {
private static final String CLASS_NAME = "calssName";//类名称
private static final String CLASS_METHOD = "calssMethod";//类方法名称
@Autowired
private LrpLogSysService lrpLogSysService;
//定义切点 @Pointcut
//在注解的位置切入代码
@Pointcut("@annotation(com.richfit.sod.appserver.common.annotation.AnnotationForLog)")
public void logPoinCut() {
}
@Around("logPoinCut()")
public Object doAroundAdvice(ProceedingJoinPoint joinPoint) throws ClassNotFoundException {
String classType = joinPoint.getTarget().getClass().getName();//获取类名 //Class<?> clazz = Class.forName(classType);//转成类对象
LrpLogSys lrpLogSys = new LrpLogSys();
Map<String,Object> map = new HashMap<String,Object>();//存放数据参数
map.put(CLASS_NAME,classType);//TODO map中放入类名称
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//从切面织入点处通过反射机制获取织入点处的方法
Method method = signature.getMethod();//获取切入点所在的方法
map.put(CLASS_METHOD,method.getName()); //TODO map中放入类方法名称
AnnotationForLog annotationForLog = method.getAnnotation(AnnotationForLog.class);
Object[] args = joinPoint.getArgs();// 请求的方法参数值
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();// 请求的方法参数名称
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
Map<String,Object> dateMap = new HashMap<String,Object>();//存放请求方法数据参数及参数值
for (int i = 0; i < args.length; i++) {
dateMap.put(paramNames[i],args[i]);//TODO 请求参数名称 和 该参数对应的值
}
map.put("dateMap",dateMap); //TODO map中放入类方法名称
}
if (annotationForLog != null) {
lrpLogSys = doLrpLogSys(annotationForLog,lrpLogSys);
lrpLogSys.setDescription(JSON.toJSONString(map));//获取的操作描述json数据
}
Object obj = null;
try {//正常日志处理
obj = joinPoint.proceed(); //可以加参数
lrpLogSys.setSuccessOrNot("1");
lrpLogSysService.save(lrpLogSys);
//logger.info(obj.toString());
return obj;
} catch (Throwable throwable) {//异常日志处理
lrpLogSys.setWhyError(throwable.getMessage());
lrpLogSys.setSuccessOrNot("0");
lrpLogSysService.save(lrpLogSys);
throwable.printStackTrace();
throw new BaseException("",throwable);
}
}
/**
* 封装成日志插入数据
* [annotationForLog, lrpLogSys]
* @return {@link LrpLogSys}
* @throws
* @author 李庆伟
* @date 2019/11/23 16:33
*/
public LrpLogSys doLrpLogSys(AnnotationForLog annotationForLog,LrpLogSys lrpLogSys){
String operationType = annotationForLog.operationType().name();//操作类型 ADD,EDIT,DEL,QUERY
String operation = annotationForLog.operation();//白话描述
String operationalEntity = annotationForLog.operationalEntity();//操作的是那个实体 Student.java%STUDENT_T%展示名称%主键
lrpLogSys.setInsertDate(new Date());
lrpLogSys.setOperationType(operationType);//获取的操作
lrpLogSys.setOperation(operation);//获取的操作描述
lrpLogSys.setOperationalEntity(operationalEntity);//对那个实体进行操作
return lrpLogSys;
}
}
4.业务代码加入注解
@Transactional
@AnnotationForLog(operationType = LogEnum.ADD,operation = "学生添加操作",operationalEntity = "Student.java/STUDENT_T")
public void add(String userChineseName, String userEnglishName, String userFrenchName) {
if(userChineseName.equals("1")){
throw new BaseException("VALUE_IS_ONE");
}
Student student = new Student();
student.setUserChineseName(userChineseName);
student.setUserEnglishName(userEnglishName);
student.setUserFrenchName(userFrenchName);
student.setCreateTime(new Date());
student.setUpdateTime(new Date());
studentMapper.insert(student);
}
5.Stringboot AOP操作日志 完成
原文链接:(284条消息) Springboot Aop 自定义注解 日志入库_点点@的博客-CSDN博客_springboot 日志入库