1. 自定义注解annotation
@Target 指定可以使用注解的类型
@Retention 指定合适使用
value指定注解值得类型
import com.sky.enumeration.OperationType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
// 操作类型
OperationType value();
}
2. 切面aspect
@Pointcut(“execution()”) 定义切入点
@Before(“pointcut()”) 在切入点之前执行方法
import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.entity.Employee;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.LocalTime;
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
/**
* 切入点
*/
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void autoFillAspectPointcut(){}
/**
* 切入点之前执行
*/
@Before("autoFillAspectPointcut()")
public void jointPoint(JoinPoint joinPoint) {
// 获取注解里面的值
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取注解
AutoFill annotation = methodSignature.getMethod().getAnnotation(AutoFill.class);
OperationType operationType = annotation.value();
// 获取参数
Object[] args = joinPoint.getArgs();
if (args==null || args.length==0) {
return;
}
// 获取更新数据
LocalDateTime time = LocalDateTime.now();
Long userId = BaseContext.getCurrentId();
Object entity = args[0];
// 根据类型进行更新
if (OperationType.INSERT.equals(operationType)) {
// 反射进行更新
try {
Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
setCreateTime.invoke(entity, time);
setCreateUser.invoke(entity, userId);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
} else if (OperationType.UPDATE.equals(operationType)) {
try {
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
// 反射更新
setUpdateTime.invoke(entity, time);
setUpdateUser.invoke(entity, userId);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
3. 使用自定义注解
@AutoFill(OperationType.UPDATE)
void update(Employee employee);
4. 枚举类型
/**
* 数据库操作类型
*/
public enum OperationType {
/**
* 更新操作
*/
UPDATE,
/**
* 插入操作
*/
INSERT
}