实际需求模板:
由于只是目前服务访问量不大,所以决定采用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查询失败,无法记录日志");
}
}
}
网友评论