1.自定义注解类
/** * @version 1.0.0, 2019/5/5 * @ClassName: OperationLog * @Description: 自定义操作日志记录注解类 * @since uem v0.0.1 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OperationLog { /** * 业务的名称,例如:"修改菜单" */ String operateName() default ""; /** * 操作内容 */ String operateContent() default ""; /** * 模块名称 */ String modelName() default ""; /** * @return 日志自定义字段描述 */ Class logDataDic() default LogDataDic.class; }
2.aop拦截
package com.dtmobile.uem.nhcm.controller.logger; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @Title: * @Description: 日志记录的拦截器拦截日志注解 * @param: * @return: * @throws: * @Author: liduo */ @Aspect @Component @Slf4j public class LogAop { /** * 成功标记 */ private final int SUCCESS = 0; /** * 执行失败标记 */ private final int FAILED = 1; /** * 日志执行器 */ @Autowired private LogExecutor logExecutor; /** * 日志切点 * @param operationLog */ @Pointcut(value = "@annotation(operationLog)") public void cutService(OperationLog operationLog) { // default pointcut } /** * 正常拦截记录日志 * @param returnObj 返回值 * @param joinPoint * @param operationLog 操作日志属性 */ @AfterReturning(pointcut = "cutService(operationLog)", returning = "returnObj") public void doAfterReturning(JoinPoint joinPoint, OperationLog operationLog, Object returnObj) { String methodName = joinPoint.getSignature().getName(); //获取拦截方法的参数 String className = joinPoint.getTarget().getClass().getName(); Object[] params = joinPoint.getArgs(); logExecutor.execute(operationLog, SUCCESS); } /** * 异常拦截记录日志 * * @param operationLog 操作日志属性 * @param joinPoint 拦截点 * @param ex 异常处理流程 */ @AfterThrowing(pointcut = "cutService(operationLog)", throwing = "ex") public void doAfterThrowing(JoinPoint joinPoint, OperationLog operationLog, Exception ex) { String methodName = joinPoint.getSignature().getName(); //获取拦截方法的参数 String className = joinPoint.getTarget().getClass().getName(); Object[] params = joinPoint.getArgs(); logExecutor.execute(operationLog, FAILED); } }
@AfterThrowing
是一种通知类型,可以确保在方法抛出异常时运行一个通知。 以下是@AfterThrowing
通知的语法:
语法
@AfterThrowing(pointcut="execution(* com.yiibai.Student.*(..))", throwing= "error")
public void afterThrowingAdvice(JoinPoint jp, Throwable error){
System.out.println("Method Signature: " + jp.getSignature());
System.out.println("Exception: "+error);
}
在上面的语法示例中 -
@AfterReturning
- 如果方法返回成功,则将函数标记为在切入点覆盖的方法之前执行的通知。@Pointcut
- 将函数标记为切入点@After
- 将函数标记为在切入点覆盖的方法之后执行的通知。execution( expression )
- 涵盖应用通知的方法的表达式。throwing
- 返回的异常名称/** * Copyright 2019 Datang Mobile Co.,Ltd. All rights reserved. * DTM PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * @Title: LogExecutor * @package: com.dtmobile.uem.nhcm.logger * @author: walker.Hu(hubing) * @date: 2019/6/29 */ package com.dtmobile.uem.nhcm.controller.logger; import com.dtmobile.uem.commons.business.process.exception.MessageConfig; import com.dtmobile.uem.commons.business.process.logger.logMng.LogFactory; import com.dtmobile.uem.commons.business.process.logger.logMng.OperateLog; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Date; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import static org.apache.commons.lang3.StringUtils.EMPTY; /** * @version 1.0.0, 2019/6/29 * @className: LogExecutor * @description: 日志执行器 */ @Component @Slf4j public class LogExecutor { /** * 默认延迟 */ private static final int OPERATE_DELAY_TIME = 10; /** * OMC. */ private static final String OMC = "OMC"; @Autowired private MessageConfig messageConfig; private LogDataMapper logDataMapper; /** * */ @Autowired private LogFactory logFactory; /** * 异步操作记录日志的线程池 */ private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); /** * 异步记录操作日志 * * @param operationLog * @param result */ public void execute(OperationLog operationLog, int result) { // 获取当前登录的用户Ip HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String loginUserName = request.getHeader("loginUserName"); String clientIp = request.getHeader("clientIp"); executor.schedule(() -> { OperateLog operateLog = createLog(operationLog, result, loginUserName, clientIp); logFactory.send(operateLog); }, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); } /** * 封装操作日志 * * @param operationLog 操作注解 * @param result 日志标记 * @return 操作日志对象 */ private OperateLog createLog(OperationLog operationLog, int result, String loginUserName, String clientIp) { OperateLog operateLog = LogFactory.createOperateLog(); String operateName = operationLog.operateName(); String operateContent = messageConfig.getMsg(operationLog.operateContent()); String modelName = operationLog.modelName(); operateLog.setTerminalType(operateContent); operateLog.setClientIp(null == clientIp ? "127.0.0.1" : clientIp); operateLog.setOperUser("".equals(loginUserName) ? "no_user_info" : loginUserName); operateLog.setStartTime(new Date()); operateLog.setEndTime(new Date()); operateLog.setNeType(OMC); operateLog.setNeObject(OMC); operateLog.setObjectType(OMC); operateLog.setOperateObject(OMC); operateLog.setModuleName(modelName); operateLog.setOperateName(operateName + "|" + operateContent); operateLog.setOperateContent(operateContent); operateLog.setResult(result); operateLog.setExtraInfo(EMPTY); return operateLog; } }
4.自定义注解的使用
@ApiOperation(value = "create task") @PostMapping() @ApiImplicitParams({@ApiImplicitParam(name = "task", value = "task to be created")}) @OperationLog(operateName = Const.OperateName.CREATE_TASK,operateContent="createTask",modelName=Const.modelName.modelName) public void create(@RequestBody Task task) { taskService.create(task); }
原文:https://www.cnblogs.com/hrf521/p/11382353.html