spring AOP自定义注解方式实现日志管理
1、编写自定义注解
package com.eshore.zswh.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author chengp
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AddOperLog {
/**
* 业务操作
*/
String value() default "";
/**
* 业务描述
*/
String desc() default "";
}
2、编写切面
package com.eshore.zswh.admin.aop;
import com.eshore.zswh.admin.service.sys.ISysOperLogService;
import com.eshore.zswh.common.annotation.AddOperLog;
import com.eshore.zswh.common.entity.sys.SysOperLog;
import com.eshore.zswh.common.exception.ApiException;
import com.eshore.zswh.common.support.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 系统日志记录 切面
*
* @author chengp
* @date 2019/10/12
*/
@Slf4j
@Aspect
@Component
public class SysLogAspect {
@Resource
private ISysOperLogService sysOperLogService;
@Around("@annotation(com.eshore.zswh.common.annotation.AddOperLog)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// 获取注解信息
MethodSignature sign = (MethodSignature) pjp.getSignature();
AddOperLog operLog = sign.getMethod().getAnnotation(AddOperLog.class);
SysOperLog log = new SysOperLog();
try {
// 开始执行
log.setOperation(operLog.value());
log.setDescription(operLog.desc());
// 执行目标方法
Object result = pjp.proceed();
// 执行成功
log.setResultCode(ResultCode.SUCCESS.getCode());
log.setResultDesc(ResultCode.SUCCESS.getMsg());
return result;
} catch (Throwable e) {
// 执行异常
if (e instanceof ApiException) {
log.setResultCode(((ApiException) e).getCode());
log.setResultDesc(e.getMessage());
} else {
log.setResultCode(ResultCode.FAILURE.getCode());
log.setResultDesc("系统错误");
}
// 这里的异常需要抛出,交给全局异常处理
throw e;
} finally {
sysOperLogService.save(log);
}
}
}
3、ApiException是自定义接口请求异常类,用来管理接口可能出现的错误
package com.eshore.mlxc.admin.exception;
import lombok.*;
import java.io.Serializable;
/**
* 接口请求异常类
*
* @author chengp
*/
@Getter
public class ApiException extends RuntimeException {
/**
* 错误码
*/
private int code;
public ApiException(IResultCode resultCode) {
this(resultCode.getCode(), resultCode.getMsg());
}
public ApiException(String msg) {
this(ResultCode.FAILURE.getCode(), msg);
}
public ApiException(int code, String msg) {
super(msg);
this.code = code;
}
public ApiException(Throwable cause) {
super(cause);
this.code = ResultCode.FAILURE.getCode();
}
}
package com.eshore.mlxc.admin.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 业务状态码枚举
*
* @author chengp
*/
@Getter
@AllArgsConstructor
public enum ResultCode implements IResultCode {
/**
* 操作成功
*/
SUCCESS(0, "执行成功"),
/**
* 业务异常
*/
FAILURE(-1, "操作失败");
/**
* 状态码
*/
private final int code;
/**
* 消息
*/
private final String msg;
}
全局异常统一处理
package com.eshore.mlxc.admin.handler;
import com.eshore.mlxc.admin.exception.ApiException;
import com.eshore.mlxc.admin.support.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局统一异常处理
*
* @author zou
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* Api接口自定义异常拦截
*
* @param e Api接口自定义异常
* @return 错误返回消息
*/
@ExceptionHandler(ApiException.class)
public Result apiExceptionHandler(ApiException e) {
log.info("Api接口自定义异常:{}", e.getMessage());
return Result.fail(e);
}
}
4、存入数据库的对象 SysOperLog
package com.eshore.zswh.common.entity.sys;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 系统操作日志
* </p>
*
* @author CodeGenerator
* @date 2019-10-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "SysOperLog对象", description = "系统操作日志")
public class SysOperLog implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "业务类型")
private String operation;
@ApiModelProperty(value = "业务描述")
private String description;
@ApiModelProperty(value = "状态")
private Integer resultCode;
@ApiModelProperty(value = "状态说明")
private String resultDesc;
@ApiModelProperty(value = "操作用户")
@TableField(fill = FieldFill.INSERT)
private String createBy;
@ApiModelProperty(value = "操作时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
}

浙公网安备 33010602011771号