[SpringBoot]自定义注解@AutoFill,实现公共字段自动填充(避免重复对时间属性初始化

对于时间属性,如createTime、updateTime在进行插入、修改操作时都要一个个初始化处理,过于麻烦。

可以自定义注解@AutoFill作用于INSERT,UPDATE操作方法上,再自定义切面类,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值。

涉及知识点:枚举、注解、AOP、反射

目录

1.自定义注解@AutoFill, 用于标示某个方法需要进行功能字段自动填充处理

2.在Mapper层对应insert、update方法上加上注解@AutoFill 

3.自定义切面,实现公共字段自动填充处理逻辑


 

老办法,缺点:过于重复和麻烦 

f70a5dfc6b814f26858b12527979df4f.png

好方法:公共字段自动填充

1.自定义注解@AutoFill, 用于标示某个方法需要进行功能字段自动填充处理

35f97158fdcc433f9764c65c3d3f32a2.png 

自定义注解:AutoFill

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 {

    // 枚举数据库类型:UPDATE INSERT 用于标示自动填充的类型
    OperationType value();
}

自定义枚举类型:OperationType

/**
 * 数据库操作类型
 */
public enum OperationType {

    /**
     * 更新操作
     */
    UPDATE,

    /**
     * 插入操作
     */
    INSERT

}

2.在Mapper层对应insert、update方法上加上注解@AutoFill 

026ceabe5cf14f4cae50585c0fb5ca98.png

1600c05e83fa4352b103d0076db0091e.png

3.自定义切面,实现公共字段自动填充处理逻辑

 ①定义切入点,即统一拦截加入了AutoFill 注解的方法

 ②编写前置通知,进行公共字段自动填充

  • 获取到当前被拦截的方法上的数据库操作类型

  • 获取到当前被拦截的方法的参数--实体对象

  • 准备赋值的数据

  • 根据当前不同的操作类型,为对应的属性通过反射来赋值

自定义切面类:AutoFillAspect

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.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.Method;
import java.time.LocalDateTime;

/**
 * 自定义切面,实现公共字段自动填充处理逻辑
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     * 切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {

    }

    /**
     * 前置通知
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("开始进行公共字段自动填充...");
        //1. 获取到当前被拦截的方法上的数据库操作类型
        MethodSignature signature = (MethodSignature)joinPoint.getSignature(); //方法签名对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); //获得方法上的对象
        OperationType operationType = autoFill.value(); //获取数据库操作类型
        //2. 获取到当前被拦截的方法的参数--实体对象
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0){
            return;
        }
        Object entity = args[0];

        //3. 准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //4. 根据当前不同的操作类型,为对应的属性通过反射来赋值
        if (operationType == OperationType.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);
                setCreateUser.invoke(entity, currentId);
                setUpdateTime.invoke(entity, now);
                setUpdateUser.invoke(entity, currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (operationType == OperationType.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) {
                e.printStackTrace();
            }
        }
    }
}

公共字段填充常量类:AutoFillConstant

/**
 * 公共字段自动填充相关常量
 */
public class AutoFillConstant {
    /**
     * 实体类中的方法名称
     */
    public static final String SET_CREATE_TIME = "setCreateTime";
    public static final String SET_UPDATE_TIME = "setUpdateTime";
    public static final String SET_CREATE_USER = "setCreateUser";
    public static final String SET_UPDATE_USER = "setUpdateUser";
}

 

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
进行表单填充Autofill扩展程序具有一个目的:在页面加载时自动填充表单字段,而无需用户进行任何交互。这是它的主要功能,但是它可以做的更多 Google Chrome浏览器具有内置的自动填充功能,但不适用于所有表单字段,并且需要您从下拉菜单中进行选择。即使您对Chrome浏览器的自动填充功能感到满意,但如果您希望获得更多自动化和强大功能,仍然可能需要此扩展程序。特点-设置并忘记:零点击即可填写表格! (还有一个手动触发选项)-最终控制:自动填充文本输入字段,textarea字段,密码字段,隐藏字段,HTML5输入甚至WYSIWYG编辑框(富文本编辑器);自动选择菜单和列表框;自动选中复选框和单选按钮;使用JavaScript自动单击按钮并自动提交表单-表单域向导:使用向导信息栏为您自动生成自动填充规则,而无需查看HTML代码-易于管理:创建配置文件以更好地组织自动填充规则-快速访问:使用工具栏图标添加自动填充规则;执行配置文件中的所有自动填充规则,并通过右键单击上下文菜单执行更多操作-放心:如果Chrome崩溃,则可以自动保存文本字段的选项-正则表达式:使用功能强大的文本匹配模式来标识要自动填充字段(支持“ lookbehind')-变量:使用特殊变量来引用其他字段值,递增/递减数字,并输出随机数据(数字,字母数字字符,甚至来自集合中的单词)-网站过滤器:在每个网站或每个网站上限制自动填充-page基础-例外:指定要从自动填充中排除的页面或整个网站-导入/导出:将设置备份到本地文件或将其导入到Firefox的自动填充插件中-键盘快捷键:使用鼠标或键盘改进的可访问性新增功能-添加了自动备份文本字段的选项-添加了随机选择菜单和切换复选框的功能-改进了对表单验证的支持-改进了动态插入的元素nts观察器-处于手动模式时自动启用上下文菜单-导入后仍然禁用了延迟范围输入-修复了手动模式不支持动态插入的字段-修复了某些包含换行符的值JavaScript错误-修复了导入问题-修复了所选字段突出显示的问题-修复了添加规则(v6.12.1)时会擦除站点过滤器的问题。隐私和安全性自动填充不会,永远不会,也永远不会通过Internet传输任何数据。所有数据始终保留在本地硬盘驱动器上。但是,此扩展名保存的数据未加密,因此保存的所有数据都是明文,尽管它将保留在硬盘上,并且只有知道外观和对硬盘有物理访问权限的人才能访问它。 支持语言:English,português (Portugal),中文 (简体)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值