步骤一
自定义注解 AutoFill
/**
* 自定义注解,用于标识某个方法需要进行功能字段自动填充处理
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
//数据库操作类型:UPDATE INSERT
OperationType value();
}
OperationType
/**
* 数据库操作类型
*/
public enum OperationType {
/**
* 更新操作
*/
UPDATE,
/**
* 插入操作
*/
INSERT
}
步骤二
自定义切面 AutoFillAspect
/**
* 自定义切面,实现公共字段自动填充处理逻辑
*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
/**
* 切入点
*/
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void pt() {
}
/**
* 前置通知,在通知中进行公共字段的赋值
*/
@Before("pt()")
public void autoFill(JoinPoint joinPoint) {
//1.获取签名对象
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//2.获取方法上的注解
AutoFill autoFill = methodSignature.getMethod().getAnnotation(AutoFill.class);
OperationType type = autoFill.value();
//3.解析:判断是增加还是更新操作
Object[] args = joinPoint.getArgs();
if (Objects.isNull(args) || args.length == 0) {
//没有参数,则不处理
return;
}
try {
//获取到当前被拦截的方法的参数--实体对象
Object target = args[0];
//准备赋值的数据
LocalDateTime now = LocalDateTime.now();
Long id = BaseContext.getCurrentId();
Class<?> clazz = target.getClass();
//根据当前不同的操作类型,为对应的属性通过反射来赋值
if (type == OperationType.INSERT) {
//为公共字段赋值
Method setCreateTimeMethod = clazz.getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME,LocalDateTime.class);
Method setCreateUserMethod = clazz.getDeclaredMethod(AutoFillConstant.SET_CREATE_USER,Long.class);
autoFillUpdateMethod(target, now, id, clazz);
//通过反射为对象属性赋值
setCreateTimeMethod.invoke(target, now);
setCreateUserMethod.invoke(target, id);
} else if (type == OperationType.UPDATE) {
autoFillUpdateMethod(target, now, id, clazz);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 更新操作自动填充
* @param target
* @param now
* @param id
* @param clazz
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private void autoFillUpdateMethod(Object target, LocalDateTime now, Long id, Class<?> clazz) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
//为公共字段赋值
Method setUpdateTimeMethod = clazz.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME,LocalDateTime.class);
Method setUpdateUserMethod = clazz.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER,Long.class);
//通过反射为对象属性赋值
setUpdateUserMethod.invoke(target, id);
setUpdateTimeMethod.invoke(target, now);
}
}
步骤三
在Mapper接口的方法上加入 AutoFill 注解
@AutoFill(value = OperationType.INSERT)