使用AOP記錄SpringBoot項目編輯前后字段的具體改變

實際需求模板:


由于只是目前服務(wù)訪問量不大,所以決定采用AOP的方式進行記錄,大概實現(xiàn)步驟為:

1.需要一個注解控制哪個API接口需要進行記錄,以及記錄的操作類型

2.需要一個解析類,來通過參數(shù)來訪問數(shù)據(jù)庫,查詢修改前的數(shù)據(jù),為后邊與實際修改后的數(shù)據(jù)進行比對來找出實際變化的列

3.由于解析方式可能不同,需要在注解中加入class選項,可以自行選擇解析類

4.由于使用的MYBATIS,是使用spring依賴注入的,需要一個工具類實現(xiàn)ApplicationContextAware接口,來從容器中獲取所需要的bean

具體實現(xiàn)代碼:

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.解析接口(之后如果需要根據(jù)具體的接口重寫實現(xiàn)類,只需實現(xiàn)該接口即可):

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);

}

默認的實現(xiàn)方式(通過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.構(gòu)建實現(xiàn)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實現(xiàn)主要代碼:

@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查詢失敗,無法記錄日志");

? ? ? ? }

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容