使用AOP记录SpringBoot项目编辑前后字段的具体改变

实际需求模板:


由于只是目前服务访问量不大,所以决定采用AOP的方式进行记录,大概实现步骤为:

1.需要一个注解控制哪个API接口需要进行记录,以及记录的操作类型

2.需要一个解析类,来通过参数来访问数据库,查询修改前的数据,为后边与实际修改后的数据进行比对来找出实际变化的列

3.由于解析方式可能不同,需要在注解中加入class选项,可以自行选择解析类

4.由于使用的MYBATIS,是使用spring依赖注入的,需要一个工具类实现ApplicationContextAware接口,来从容器中获取所需要的bean

具体实现代码:

1.控制注解:

import com.baomidou.mybatisplus.service.IService;

import com.gameley.common.parser.DefaultContentParse;

import java.lang.annotation.*;

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD})

public @interface EnableGameleyLog {

String name()default "";

    Class parseclass()default DefaultContentParse.class;

    Class serviceclass()default IService.class;

}

字段含义:

name:具体的操作是什么 例如新建,编辑,更新

parseclass:指定的解析类

serviceclass:所用到的service类,需要通过该class,通过getbean方法从容器中获取所需的bean

2.解析接口(之后如果需要根据具体的接口重写实现类,只需实现该接口即可):

import com.gameley.common.EnableGameleyLog;

import com.gameley.common.Interceptor.ModifyAspect;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public interface ContentParser {

final static Loggerlogger = LoggerFactory.getLogger(ContentParser.class);

    public ObjectgetResult(Integer id, EnableGameleyLog enableGameleyLog);

}

默认的实现方式(通过id进行查找):

import com.baomidou.mybatisplus.service.IService;

import com.gameley.common.EnableGameleyLog;

import com.gameley.common.util.SpringUtil;

public class DefaultContentParseimplements ContentParser {

@Override

public Object getResult(Integer id, EnableGameleyLog enableGameleyLog) {

IService service=null;

        Class cls=enableGameleyLog.serviceclass();

        service = (IService) SpringUtil.getBean(cls);

        return  service.selectById(id);

    }

}


3.构建实现ApplicationContextAware的工具类:

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

@Component

public class SpringUtilimplements ApplicationContextAware {

private static ApplicationContextapplicationContext;

    @Override

    public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {

if(SpringUtil.applicationContext ==null) {

SpringUtil.applicationContext = applicationContext;

        }

}

//获取applicationContext

    public static ApplicationContextgetApplicationContext() {

return applicationContext;

    }

//通过name获取 Bean.

    public static ObjectgetBean(String name){

return getApplicationContext().getBean(name);

    }

//通过class获取Bean.

    public static T getBean(Class clazz){

return getApplicationContext().getBean(clazz);

    }

//通过name,以及Clazz返回指定的Bean

    public static T getBean(String name,Class clazz){

return getApplicationContext().getBean(name, clazz);

    }

}

4.AOP实现主要代码:

@Before("@annotation(enableGameleyLog)")

public void doBefore(JoinPoint joinPoint, EnableGameleyLog enableGameleyLog){

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

    HttpServletRequest request = attributes.getRequest();

    Object info=joinPoint.getArgs()[0];

    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    operateLog.setUsername(BaseContextHandler.getName());

    operateLog.setModifyip(ClientUtil.getClientIp(request));

    operateLog.setModifydate(sdf.format(new Date()));

    operateLog.setModifyobject(request.getRequestURL().toString());

    operateLog.setModifyname(enableGameleyLog.name());

    operateLog.setModifycontent("");

    if(ModifyName.UPDATE.equals(enableGameleyLog.name())){

Object result=ReflectionUtils.getFieldValue(info,"id");

        if(resultinstanceof String){

id= Integer.parseInt((String) result);

        }else if(resultinstanceof Integer){

id= (Integer) result;

        }

}

if(id!=null){

try {

ContentParser contentParser= (ContentParser) enableGameleyLog.parseclass().newInstance();

            oldObject=contentParser.getResult(id,enableGameleyLog);

        }catch (Exception e) {

logger.error("service加载失败:",e);

        }

}else{

if(ModifyName.UPDATE.equals(enableGameleyLog.name())){

logger.error("id查询失败,无法记录日志");

        }

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容