1.定义GateOpLog
import java.lang.annotation.*; /** * 操作日志记录 * @author codefulture */ @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface GateOpLog { /** * 说明 */ String content() default ""; /** * 业务模块类型 */ String operationType(); /** * 接口地址 */ String interfacePath(); }
2.定义切面,Pointcut指向GateOpLog
/** * 此类主要是用来用户保留操作记录 * 主要记录的内容有:id,操作人,业务模块、请求方法、请求地址、操作时间 * * @author codefulture */ @Aspect @Slf4j @Component("gateOpLogAspect") public class GateOpLogAspect { @Autowired private GateOperationLogMapper gateOperationLogMapper; @Pointcut("@annotation(cn.com.xxx.aspect.GateOpLog)") public void gateOpLogAspect() { } @Before(value = "gateOpLogAspect()") public void beforeMethod(JoinPoint joinPoint) throws Exception { log.info("==========执行业务操作日志留痕==============="); this.saveLog(joinPoint); } public void saveLog(JoinPoint proceedingJoinPoint) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod(); String methodName = method.getName(); String gateId = ""; GateOpLog opLog = method.getAnnotation(GateOpLog.class); String operationType = opLog.operationType(); String interfacePath = opLog.interfacePath(); List<Object> args = Arrays.asList(proceedingJoinPoint.getArgs()); if (args.size() > 0) { Object entitys = args.get(0); // 如果参数是List类型,取第一个对象 if (entitys instanceof List) { Object entity = ((List<?>) entitys).get(0); Field rsIdFiled = entity.getClass().getDeclaredField("id"); rsIdFiled.setAccessible(true); // 获取ID gateId = StringUtils.defaultString((String) rsIdFiled.get(entity), StringUtils.EMPTY); } else { Field rsIdFiled = entitys.getClass().getDeclaredField("id"); rsIdFiled.setAccessible(true); // 获取ID gateId = StringUtils.defaultString((String) rsIdFiled.get(entitys), StringUtils.EMPTY); } } operatingLog(gateId, methodName, operationType, interfacePath); } catch (Exception e) { log.error("******发生异常******", e.getMessage()); } } /** * 保留业务操作日志 * @param methodName 方法名 * @param interfacePath 接口地址 */ public void operatingLog(String gateId, String methodName, String operationType,String interfacePath) { Subject subject = SecurityUtils.getSubject(); JwtToken jwtToken = (JwtToken) subject.getPrincipal(); String currentUsername = jwtToken.getNAME(); GateOperationLog logBean = new GateOperationLog(); logBean.setId(UuidUtil.uuid()); logBean.setGateId(gateId); logBean.setOperationType(operationType); logBean.setMethodname(methodName); logBean.setStatus("1"); logBean.setOperationUser(currentUsername); logBean.setCreatetime(new Date()); logBean.setAuditUser(currentUsername); logBean.setAuditTime(new Date()); logBean.setInterfacePath(interfacePath); gateOperationLogMapper.insert(logBean);//入库的mapper } }
3.Controller的接口中使用
@GateOpLog(operationType = "操作类型", interfacePath = "/app/test/saveSubmit") @PostMapping("/saveSubmit") public ResponseResult<String> saveSubmit(@RequestBody GeoMatchQuery query){ //业务代码 }
测试,在调用Controller的接口时,会先执行 记录日志 的切面方法