项目情况:
pmdb项目开发过程中需要实现一个操作日志的功能,即将对数据库指定表的增删改查操作进行记录。我采用的是面向切面编程+自定义注解的方式实现的。这种方式的优点是,可以指定哪些方法的操作被记录。
我在开发中遇到的问题是:
1.我们的数据库表是有业务主键的,无法根据数据库命名规则来获取到。(日志记录中需要存入业务主键的值);
2.有的表没有业务主键,可以通过命名规则根据表名来获得Id字段名。但是有的表有多个业务主键,这就需要进行特殊的处理。
解决方案:
第一步:添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
第二步:编写自定义注解类
import java.lang.annotation.*;
// 自定义注释
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodRemark {
// 操作描述
String remark() default "";
// 0:查 1:增 2:删 3:改内容 4: archive 5: unarchive'
String opType() default "0";
//所操作表名
String tableName() default "";
//主键字段名称
String keyName() default "";
//业务主键名称
String[] businessKeyName() default {""};
}
第三步:编写切面类(这里面如何过去请求参数和响应参数并进行处理是关键)
import com.handlecar.basf_pmdb_service.common.CommonConstant;
import com.handlecar.basf_pmdb_service.dto.AbstractInputDto;
import com.handlecar.basf_pmdb_service.dto.AbstractOutputDto;
import com.handlecar.basf_pmdb_service.entity.log.BusinessCostDataLog;
import com.handlecar.basf_pmdb_service.service.log.LogService;
import com.handlecar.basf_pmdb_service.tools.JsonUtils;
import com.handlecar.basf_pmdb_service.tools.Util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
@Component
@Aspect
public class OperationLogs {
private static Logger logger = LoggerFactory