Browse Source

AOP注解实现,记录日志

master
luogw 1 month ago
parent
commit
36bb721f82
  1. 2
      src/main/java/com/project/information/controller/ProductLineController.java
  2. 16
      src/main/java/com/project/operation/annotation/OperationLog.java
  3. 115
      src/main/java/com/project/operation/aop/OperationLogAspect.java
  4. 24
      src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java
  5. 10
      src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java
  6. 29
      src/main/java/com/project/operation/domain/dto/OperationLogDTO.java
  7. 49
      src/main/java/com/project/operation/domain/entity/OperationLogEntity.java
  8. 8
      src/main/java/com/project/operation/domain/service/OperationLogBaseService.java
  9. 10
      src/main/java/com/project/operation/domain/service/SaveOperationLogDomainService.java
  10. 12
      src/main/java/com/project/operation/domain/service/impl/OperationLogBaseServiceImpl.java
  11. 21
      src/main/java/com/project/operation/domain/service/impl/SaveOperationLogDomainServiceImpl.java
  12. 9
      src/main/java/com/project/operation/mapper/OperationLogMapper.java

2
src/main/java/com/project/information/controller/ProductLineController.java

@ -5,6 +5,7 @@ import com.project.base.domain.result.Result;
import com.project.information.application.ProductLineApplicationService;
import com.project.information.domain.dto.ProductLineDTO;
import com.project.information.domain.param.ProductLineParam;
import com.project.operation.annotation.OperationLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -29,6 +30,7 @@ public class ProductLineController {
}
@GetMapping("/treeList")
@OperationLog(module = "查询",description = "查询树形产品线")
public Result<List<ProductLineDTO>> treeList(ProductLineParam param) throws Exception {
return productLineApplicationService.treeList(param);
}

16
src/main/java/com/project/operation/annotation/OperationLog.java

@ -0,0 +1,16 @@
package com.project.operation.annotation;
import java.lang.annotation.*;
/**
* 自定义操作日志注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
//操作模块
String module() default "";
//操作描述
String description() default "";
}

115
src/main/java/com/project/operation/aop/OperationLogAspect.java

@ -0,0 +1,115 @@
package com.project.operation.aop;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.project.base.domain.result.Result;
import com.project.ding.domain.dto.LoginDTO;
import com.project.ding.utils.JwtUtils;
import com.project.operation.annotation.OperationLog;
import com.project.operation.application.impl.OperationLogApplicationService;
import com.project.operation.domain.dto.OperationLogDTO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
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 java.lang.reflect.Method;
/**
* 操作日志AOP切面
*/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class OperationLogAspect {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private OperationLogApplicationService operationLogApplicationService;
private final ThreadLocal<OperationLogDTO> operationLogDTOThreadLocal = new ThreadLocal<>();
//定义切点,拦截所有添加@OperationLog注解的方法
@Pointcut("@annotation(com.project.operation.annotation.OperationLog)")
public void pointcutOperationLog() {}
//环绕通知,在方法执行前后拦截,收集日志
@Around("pointcutOperationLog()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//获取开始时间
long startTime = System.currentTimeMillis();
OperationLogDTO operationLogDTO = new OperationLogDTO();
//获取客户端IP和操作用户
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = requestAttributes.getRequest();
operationLogDTO.setClientIp(request.getRemoteAddr());
String header = request.getHeader("Authorization");
if (StringUtils.isNotBlank(header) && header.startsWith("Bearer ")) {
String token = header.substring(7);
String userId = jwtUtils.parseToken(token).getSubject();
operationLogDTO.setCreatorId(Long.parseLong(userId));
}
}
//获取方法信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 方法全路径:包名+类名+方法名
operationLogDTO.setMethod(method.getDeclaringClass().getName() + "." + method.getName());
//获取操作信息
OperationLog annotation = method.getAnnotation(OperationLog.class);
operationLogDTO.setModule(annotation.module());
operationLogDTO.setDescription(annotation.description());
Object businessResult;
try {
operationLogDTOThreadLocal.set(operationLogDTO);
businessResult = joinPoint.proceed();
operationLogDTO.setResult(0);
}catch (Exception e){
operationLogDTO.setResult(1);
operationLogDTO.setException(e.getMessage());
throw e;
}finally {
operationLogDTO.setCostTime(System.currentTimeMillis() - startTime);
//保存日志
operationLogApplicationService.saveOperationLog(operationLogDTO);
}
return businessResult;
}
@AfterReturning(returning = "result",pointcut = "pointcutOperationLog()")
public void afterReturning(Object result) throws Throwable {
OperationLogDTO operationLogDTO = operationLogDTOThreadLocal.get();
if (operationLogDTO == null) {
return; // 无上下文,直接返回
}
try {
//获取当前登陆用户
if(operationLogDTO.getMethod().contains("getToken") && result instanceof Result){
LoginDTO data = ((Result<LoginDTO>) result).getData();
String userId = jwtUtils.parseToken(data.getToken()).getSubject();
operationLogDTO.setCreatorId(Long.parseLong(userId));
}
}finally {
operationLogDTOThreadLocal.remove();
}
}
}

24
src/main/java/com/project/operation/application/OperationLogApplicationServiceImpl.java

@ -0,0 +1,24 @@
package com.project.operation.application;
import com.project.operation.application.impl.OperationLogApplicationService;
import com.project.operation.domain.dto.OperationLogDTO;
import com.project.operation.domain.service.OperationLogBaseService;
import com.project.operation.domain.service.SaveOperationLogDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OperationLogApplicationServiceImpl implements OperationLogApplicationService {
@Autowired
private SaveOperationLogDomainService saveOperationLogDomainService;
/**
* 保存日志
*/
@Override
public void saveOperationLog(OperationLogDTO operationLogDTO) {
saveOperationLogDomainService.saveOperationLog(operationLogDTO);
}
}

10
src/main/java/com/project/operation/application/impl/OperationLogApplicationService.java

@ -0,0 +1,10 @@
package com.project.operation.application.impl;
import com.project.operation.domain.dto.OperationLogDTO;
public interface OperationLogApplicationService {
/**
* 保存操作日志
*/
void saveOperationLog(OperationLogDTO operationLogDTO);
}

29
src/main/java/com/project/operation/domain/dto/OperationLogDTO.java

@ -0,0 +1,29 @@
package com.project.operation.domain.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.project.base.domain.dto.BaseDTO;
import jakarta.persistence.Column;
import jakarta.persistence.Id;
import lombok.Data;
import org.hibernate.annotations.Comment;
@Data
public class OperationLogDTO extends BaseDTO {
private Long id;
private String module;
private String description;
private Integer result;
private String method;
private String exception;
private Long costTime;
private String clientIp;
}

49
src/main/java/com/project/operation/domain/entity/OperationLogEntity.java

@ -0,0 +1,49 @@
package com.project.operation.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.project.base.domain.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@Table(name = "evaluator_operation_log")
@Entity
@TableName(value = "evaluator_operation_log")
@EqualsAndHashCode(callSuper = true)
public class OperationLogEntity extends BaseEntity {
@TableId(value = "id" , type = IdType.ASSIGN_ID)
@Id
private Long id;
@Column(name = "module", columnDefinition = "varchar(255) comment '操作模块'")
private String module;
@Column(name = "description" , columnDefinition="varchar(255) comment '操作描述'")
private String description;
/** 操作结果 */
@Column(name = "result")
@Comment("操作结果,0-成功, 1-失败")
private Integer result;
@Column(name = "method", columnDefinition="varchar(255) comment '操作方法路径'")
private String method;
@Column(name = "exception", columnDefinition="varchar(255) comment '异常信息(失败时记录)'")
private String exception;
/** 操作耗时(毫秒) */
@Column(name = "cost_time")
@Comment("操作耗时(毫秒)")
@TableField("cost_time")
private Long costTime;
@Column(name = "client_ip", columnDefinition="varchar(100) comment '客户端IP'")
@TableField("client_ip")
private String clientIp;
}

8
src/main/java/com/project/operation/domain/service/OperationLogBaseService.java

@ -0,0 +1,8 @@
package com.project.operation.domain.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.project.operation.domain.dto.OperationLogDTO;
import com.project.operation.domain.entity.OperationLogEntity;
public interface OperationLogBaseService extends IService<OperationLogEntity> {
}

10
src/main/java/com/project/operation/domain/service/SaveOperationLogDomainService.java

@ -0,0 +1,10 @@
package com.project.operation.domain.service;
import com.project.operation.domain.dto.OperationLogDTO;
public interface SaveOperationLogDomainService {
/**
* 保存操作日志
*/
void saveOperationLog(OperationLogDTO operationLogDTO);
}

12
src/main/java/com/project/operation/domain/service/impl/OperationLogBaseServiceImpl.java

@ -0,0 +1,12 @@
package com.project.operation.domain.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.operation.domain.dto.OperationLogDTO;
import com.project.operation.domain.entity.OperationLogEntity;
import com.project.operation.domain.service.OperationLogBaseService;
import com.project.operation.mapper.OperationLogMapper;
import org.springframework.stereotype.Service;
@Service
public class OperationLogBaseServiceImpl extends ServiceImpl<OperationLogMapper, OperationLogEntity> implements OperationLogBaseService {
}

21
src/main/java/com/project/operation/domain/service/impl/SaveOperationLogDomainServiceImpl.java

@ -0,0 +1,21 @@
package com.project.operation.domain.service.impl;
import com.project.operation.domain.dto.OperationLogDTO;
import com.project.operation.domain.entity.OperationLogEntity;
import com.project.operation.domain.service.OperationLogBaseService;
import com.project.operation.domain.service.SaveOperationLogDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SaveOperationLogDomainServiceImpl implements SaveOperationLogDomainService {
@Autowired
private OperationLogBaseService operationLogBaseService;
@Override
public void saveOperationLog(OperationLogDTO operationLogDTO) {
OperationLogEntity entity = operationLogDTO.toEntity(OperationLogEntity::new);
operationLogBaseService.save(entity);
}
}

9
src/main/java/com/project/operation/mapper/OperationLogMapper.java

@ -0,0 +1,9 @@
package com.project.operation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.project.operation.domain.entity.OperationLogEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OperationLogMapper extends BaseMapper<OperationLogEntity> {
}
Loading…
Cancel
Save