在最近的项目中需要记录操作日志。
在学习spring的时候,里面的重点有一项就是面向切面编程,所以当项目需要日志记录的时候第一方案想到的就是自定义注解加AOP了。
- 创建需要拦截的注解,或者你也可以通过配置切入点,通过路径来配置需要拦截的方法
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AuditLog {
AuditType auditType();
}
- 自定义切入点,以及拦截后的实现方法。
import cn.iyuta.golive.v2.tool.ParamBiz;
import org.apache.commons.lang3.BooleanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AuditLogAspect {
@Autowired
private ParamBiz paramBiz;
@Pointcut(value = "@annotation(cn.iyuta.golive.filter.auditlog.AuditLog)")
public void methodPointcut() {
}
@Around("methodPointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
// 获取注解中的值
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
AuditLog annotation = methodSignature.getMethod().getAnnotation(AuditLog.class);
AuditType auditType = annotation.auditType();
// 获取参数
Object[] args = joinPoint.getArgs();
// 获取之前的数据
// Proceed with the method execution
Object result = joinPoint.proceed();
// 获取改变后的数据
// 添加日志
return result;
}
}
- 如果使用注解,将注解添加到需要拦截的方法中
@Override
@AuditLog(auditType = AuditType.UserType)
public void addProductCart(final CartAddRequest request) {
ProductDTO product = productAdapter.findById(request.getProductId(), request.getMarket(), request.getLocale());
if (request.getQuantity() == null) {
request.setQuantity(1);
}
if (request.getUnitPrice() == null) {
request.setUnitPrice(new BigDecimal(product.getProductPrice()));
}
cartSystem.addProductCart(request);
}
如上只是一个大概的框架,比如怎么获取修改前的数据,怎么获取修改后的数据,怎么存储数据,还需要配合相应的业务来进行实施。
举一个简单的例子。
- 可以在参数中判断有无ID来判断是新增还是修改。
- 通过查询时候是否能查到记录判断操作日志是否删除。
- 通过方法执行前来收集修改前的数据
- 通过方法执行后来收集改变后的数据
其他实现方案:
在数据库中可以通过Trigger 来实现,使用Trigger来触发增,删,改操作来往另外一张表中插入修改的历史数据。具体的Trigger创建方法可以参考 mysqsl Trigger使用