AOP 实现操作日志管理

AOP + 注解实现操作日志管理功能

在项目开发过程中,少不了日志管理,今天公司就给我了一个任务,实现日志管理,在这简单介绍AOP实现操作日志功能。

1,创建数据表操作日志数据表

 

CREATE TABLE `log_operate` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '操作者',
`status` tinyint(4)  DEFAULT '0' COMMENT '状态: 1 成功,-1 失败',
`modules` varchar(191)  DEFAULT NULL COMMENT '模块',
`method` varchar(255) DEFAULT NULL COMMENT '操作方法url',
`operation` varchar(100) DEFAULT NULL COMMENT '操作:新增、详情、编辑、删除',
`content` text  COMMENT '操作详情:编辑,删除',
`ip` varchar(100)  DEFAULT NULL COMMENT 'IP地址',
`created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='操作日志记录表';

2,创建日志实体类文件

@Data
@TableName("log_operate")
public class LogOperate implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private Long userId;
private String modules;
private String method;
private String operation;
private String content;
private String ip;
private Integer status;
private Date createdAt;
}

 

3,在xml文件中引入AOP包

 

<!-- aop依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>

 

4,自定义Log注解类(根据需要自定义参数个数及类型)

 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String operModu() default "";
String value() default "";
int operType() default 0; //列表1 ,非列表 -1
}

 

5,切面日志配置

 

/**
* @author Promise
* @description 切面日志配置
*/
@Aspect
@Component
public class LogAsPect {
private final static Logger log = org.slf4j.LoggerFactory.getLogger(LogAsPect.class);

protected static Subject getSubject() {
return SecurityUtils.getSubject();
}

protected SysEmployee getCurrentUser() {
return (SysEmployee) getSubject().getPrincipal();
}

@Autowired
private HospLogOperateService hospLogOperateService;

//表示匹配带有自定义注解的方法
@Pointcut("@annotation(com.mly.oa.hospital.config.Log)")
public void pointcut() {
}

/**
* 处理完请求后执行
* */
@AfterReturning(pointcut = "pointcut()",returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint,Object jsonResult){
handleLog(joinPoint,null,jsonResult);
}


/**
* 捕获异常
* */
@AfterThrowing(value = "pointcut()",throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint,Exception e){
handleLog(joinPoint,e,null);
}

protected void handleLog (final JoinPoint joinPoint,final Exception e,Object jsonResult){
try{
LogOperate logOperate = new LogOperate();
Log controllerLog = getAnnotationLog(joinPoint);
if(controllerLog == null){
return ;
}
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 请求的方法名
String methodName = signature.getName();
// 请求的方法参数值
String args = Arrays.toString(joinPoint.getArgs());
// 获取request
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
Log userAction = method.getAnnotation(Log.class);
// log.info("当前登陆人:{},类名:{},方法名:{},参数:{},执行时间:{}",1, className, methodName, args);
int type = 0;
if (userAction != null) {
// 注解上的描述
logOperate.setOperation(userAction.value());//操作方法
logOperate.setModules(userAction.operModu());//模块
type = userAction.operType();
}
//异常处理
if(e!=null){
logOperate.setStatus(-1);
logOperate.setContent(e.getMessage());
}else{
logOperate.setStatus(1);
if(type==-1){
//获取唯一id参数
if(methodName=="delete"){
int s1 = Arrays.toString(joinPoint.getArgs()).indexOf("[")+1;
int s2 = Arrays.toString(joinPoint.getArgs()).indexOf(",");
String id = Arrays.toString(joinPoint.getArgs()).substring(s1,s2);
logOperate.setContent(userAction.operModu()+","+userAction.value());
}else{
int s1 = Arrays.toString(joinPoint.getArgs()).indexOf("(")+1;
int s2 = Arrays.toString(joinPoint.getArgs()).indexOf("hid")-2;
String id = Arrays.toString(joinPoint.getArgs()).substring(s1,s2);
logOperate.setContent(userAction.operModu());
}
}else{
logOperate.setContent(userAction.operModu());
}
}
Long userId = getCurrentUser().getId();
logOperate.setUserId(userId);
logOperate.setMethod(className + "." + methodName + "()");
logOperate.setIp(IpUtil.getIpAddr(request));
logOperate.setCreatedAt(new Date());

hospLogOperateService.store(logOperate);
}catch(Exception exp){
log.error("日志异常信息 {}",exp);
}
}

private Log getAnnotationLog(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if(method!=null){
return method.getAnnotation(Log.class);
}
return null;
}

 

6,配置文件中开启aop切面(我的是application.properties)

 

  spring.aop.auto=true

 

7,去类中使用注解

 

    @Log(operModu = "xxx",value="xx",operType = i)
@PostMapping("/update")
public String update(xxx) {
xxxxxx.........
  }

 

posted @ 2021-11-02 10:40  GXF_feige  阅读(602)  评论(0)    收藏  举报