AOP切面自动填充insert和update的字段值避免重复代码
AOP切面自动填充insert和update的字段值避免重复代码
整体流程:定义注解 -> 编写切面 -> 拦截方法 -> 反射赋值。
-
自定义注解@AutoFill,并在mapper类上添加注解
package com.sky.annotation; 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; /** * @author H * 自定义注解,用于标识需要进行公共字段自动填充的方法 * @create 2026/3/21 17:12 */ @Target(ElementType.METHOD)//指定只能加载方法上 @Retention(RetentionPolicy.RUNTIME)//在运行时依旧有效,并可以通过反射获取到 public @interface AutoFill { OperationType value();//OperationType 调用一个枚举类用于区分是insert或者update }OperationType.java
package com.sky.enumeration; /** * 数据库操作类型 */ public enum OperationType { /** * 更新操作 */ UPDATE, /** * 插入操作 */ INSERT } -
编写切面类方法并设置切入点
package com.sky.aspect; import com.sky.annotation.AutoFill; import com.sky.constant.AutoFillConstant; import com.sky.context.BaseContext; 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; /** * @author H * @create 2026/3/21 17:20 */ @Slf4j @Component @Aspect public class AutoFillAspect { /** * 切入点,精准筛选出只有mapper包下添加了AutoFill注解的所有方法,使用&&连接符要求满足两个条件 */ @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)") public void autoFillPointCut(){} } -
拦截匹配方法并反射赋值
/** * 前置通知,在通知中进行公共字段的自动填充 */ @Before("autoFillPointCut()") public void autoFill(JoinPoint joinPoint){ log.info("开始进行公共字段的自动填充..."); //首先获取到拦截到的请求方法的数据库操作类型 MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法的签名对象,将Signature父类接口强制转换为子接口MethodSignature才能拥有getMethod方法才能获取到Method对象并执行后续操作 AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象 OperationType operationType = autoFill.value();//获得数据库操作类型 //获取到当前被拦截的方法的参数--实体对象 Object[] args = joinPoint.getArgs(); if(args == null || args.length == 0){ return; } Object entity = args[0]; //准备赋值的数据 LocalDateTime now = LocalDateTime.now(); Long currentId = BaseContext.getCurrentId(); //根据不同的操作类型,为对应的属性通过反射来赋值 if(operationType == OperationType.INSERT){ //insert方法为4个公共字段赋值 try { Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class); Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class); Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class); Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class); //通过反射为字段赋值 setCreateTime.invoke(entity,now); setUpdateTime.invoke(entity,now); setCreateUser.invoke(entity,currentId); setUpdateUser.invoke(entity,currentId); } catch (Exception e) { throw new RuntimeException(e); } }else if(operationType == OperationType.UPDATE){ //update方法为2个公共字段赋值 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,now); setUpdateUser.invoke(entity,currentId); } catch (Exception e) { throw new RuntimeException(e); } } } -
在定义的mapper类中需要的方法上添加注解
@Insert("insert into employee (name, username,password, phone, sex, id_number,create_time,update_time,create_user,update_user,status) values (#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})") @AutoFill(value = OperationType.INSERT)//添加注解并指定类型 void insert(Employee employee); Page<Employee> page(EmployeePageQueryDTO employeePageQueryDTO); @AutoFill(value = OperationType.UPDATE) void updateById(Employee employee);

浙公网安备 33010602011771号