spring 使用aop切面实现系统操作日志记录

前言:在后台管理系统中,我们通常会有一个用户操作日志的模块,方便管理和日常bug排查修复,最常用的就是使用aop切面实现。
1.添加maven依赖,只贴出了aop包,其他缺失的自己添加

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2.创建系统操作日志注解类(简单的只需要一个描述属性)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    String  description() default "";
}

3.创建aop切面实现类

@Component
@Aspect
public class OperationLogAspect {
	
	/**
	 * 日志
	 */
	private static final Logger logger = LogManager.getLogger(OperationLogAspect.class);

	@Autowired
	private HttpServletRequest request;
	
	//此处是日志实现service类
	@Resource
	private SysOperationLogService sysOperationLogService;
	
   //Pointcut里面是刚创建的注解全类名
	@Pointcut("@annotation(com.XX.anno.OperationLog)")
	public void operationLogPointcut() {

	}
   //此处可以用before,around,之所以用afterReturning是想把接口的返回结果记录下来
   //如果要获取接口返回结果returning = "result"是必须的,入参里也加入Object result
   //之所以用Object result类型,是因为怕接口返回值不一致
   //我的项目中 是使用自定义的父抽象类ResultResponse 代替Object result
   //否则某接口返回类型对应不上,该aop在此接口中不起作用
	@AfterReturning(value = "operationLogPointcut()", returning = "result")
	public void saveSysOperationLog(JoinPoint joinPoint, ResultResponse result) {
		//自定义的系统操作日志实体类
		SysOperationLog log=new SysOperationLog();
		try {
		    //joinPoint.getArgs()是入参
			log.setInputBody(JSONObject.toJSONString(joinPoint.getArgs()));
			//result是返回结果,对返回结果做字符长度限制
			String response=JSONObject.toJSONString(result);
			if(response.length()>4950){
				log.setOputputBody(response.substring(0,4950));
			}else{
				log.setOputputBody(response);
			}
			//返回值中自定义的状态,判断接口成功还是失败
			log.setStatus(String.valueOf(result.getErrorNo()));
			//请求路径,例如/login/adminlogin
			log.setApiAddress(request.getRequestURI());
			try {
			    //获取类名,方法名,和注解里的description属性值
				Class clazz = joinPoint.getTarget().getClass();
				String methodName = joinPoint.getSignature().getName();
				Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();
				Method method = clazz.getMethod(methodName,parameterTypes);
				OperationLog anno = method.getAnnotation(OperationLog.class);
				log.setDescription(anno.description());
				log.setMethod(method.getName());
				log.setCreateTime(new Date());
			} catch (Exception ex) {
				logger.error("获取方法注解失败!");
			}
			//系统操作日志新增方法
			sysOperationLogService.insert(log);
		}catch (Exception e){
			logger.error("记录系统操作日志失败!"+e.toString());
		}
	}
}

4.在controller层的方法中添加日志注解

    @GetMapping("/findDepartment")
    @OperationLog(description = "查询诊所启用的科室")
    public ResultResponse<List<Department>> findDepartment() {
    }

主要的几个类完成了,至于日志实体类和日志service类,根据需求自己创建就行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值