基于Spring AOP自动填充字段

文章目录

Spring AOP简介

Spring AOP(Aspect-Oriented Programming)是 Spring 框架中的一个核心模块,用于实现面向切面编程。它提供了一种将横切关注点(cross-cutting concerns)与核心业务逻辑分离的机制。

在传统的面向对象编程中,我们通常按照功能模块对代码进行划分,比如将业务逻辑、数据访问、日志记录等功能分别封装在不同的类中。然而,某些功能可能会跨越多个模块,比如日志记录、事务管理、权限控制等,这就是所谓的横切关注点。横切关注点的存在会导致代码的重复性增加,降低了代码的可维护性和灵活性。

Spring AOP 提供了一种通过将横切关注点从核心业务逻辑中抽离出来,并在特定的执行点(如方法调用、方法执行前后、异常抛出等)插入切面(Aspect)的方式来解决这个问题。通过 AOP,我们可以将这些横切关注点封装到独立的切面中,然后在需要的地方将这些切面织入到应用程序中,而无需修改核心业务逻辑的代码。

例子

当你需要在 Spring Boot 项目中实现公共字段自动填充时,可以使用 Spring AOP 来简化开发。以下是实现这一目标的步骤:

  1. 自定义注解 AutoFill

    • 创建一个自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法。这些方法通常是 Mapper 中涉及到插入更新的方法。
    • AutoFill 注解中,指定数据库操作类型(INSERT 或 UPDATE)。
  2. 自定义切面类 AutoFillAspect

    • 创建一个切面类 AutoFillAspect,用于统一拦截加入了 AutoFill 注解的方法。
    • 在切面中,通过反射为公共字段赋值。
    • 切面应该定义切入点拦截哪些请求)和通知对拦截的请求进行额外的代码补充与增强)。
  3. 在 Mapper 的方法上加入 AutoFill 注解

    • 在需要进行公共字段自动填充的 Mapper 方法上加入 AutoFill 注解。
    • 根据操作类型(INSERT 或 UPDATE),自动填充相应的字段值。

具体实现步骤如下:

  1. 自定义注解 AutoFill

    package com.hac.annotation;
    
    import com.hac.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(); // 自己定义一个枚举类OperationType。数据库操作类型:UPDATE 或 INSERT
    }
    
  2. 自定义切面 AutoFillAspect

    package com.hac.aspect;
    
    import com.hac.annotation.AutoFill;
    import com.hac.constant.AutoFillConstant;
    import com.hac.context.BaseContext;
    import com.hac.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 {
    	// 切点
    	// 这个切点表达式表示匹配 com.hac.mapper 包及其子包下的所有类的所有方法,并且这些方法被 @AutoFill 注解标注
    	// 当匹配到这些连接点时,与该切点关联的切面(Aspect)中定义的通知(Advice)就会被触发,执行相应的切面逻辑。
        @Pointcut("execution(* com.hac.mapper.*.*(..)) && @annotation(com.hac.annotation.AutoFill)")
        public void autoFillPointCut() {}
    	// 通知
        @Before("autoFillPointCut()")
        public void autoFill(JoinPoint joinPoint) { //  JoinPoint 是连接点,表示被拦截的方法。
            // 获取到当前被拦截的方法上的数据库操作类型
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            AutoFill autoFill = method.getAnnotation(AutoFill.class);
    
            // 根据操作类型为公共字段赋值
            if (autoFill.value() == OperationType.INSERT) {
                // 设置 createTime、updateTime、createUser、updateUser
                // ...
            } else if (autoFill.value() == OperationType.UPDATE) {
                // 设置 updateTime、updateUser
                // ...
            }
        }
    }
    
  3. 在 Mapper 的方法上加入 AutoFill 注解

    package com.hac.mapper;
    
    import com.hac.annotation.AutoFill;
    import com.hac.enumeration.OperationType;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface YourMapper {
        @AutoFill(OperationType.INSERT)
        void insertData(YourEntity entity);
    
        @AutoFill(OperationType.UPDATE)
        void updateData(YourEntity entity);
    }
    

基于 Spring AOP 实现公共字段自动填充,涉及到了一些 AOP 相关的术语。让我来详细解释一下这些术语:

  1. 切面类(Aspect)

    • 切面类,横切关注点的模块化
    • 在公共字段自动填充的场景中,切面负责拦截加入了 AutoFill 注解的方法,并在方法执行前后进行功能增强。
  2. 切点(PointCut)

    • 指定了哪些方法会被拦截【切点表达式定义了何时应该激活切面】
    • 在公共字段自动填充的流程中,切点是指加入了 AutoFill 注解的方法。
  3. 通知(Advice)

    • 通知是切面中的具体逻辑代码,用于在切点位置执行特定的操作。通知则指定了在那些点应该执行的操作。【拦截的方法执行前,先执行通知】
    • 在公共字段自动填充的场景中,通知负责根据操作类型(INSERT 或 UPDATE)为公共字段赋值。

总之,Spring AOP 提供了一种灵活且强大的方式来增强应用程序的功能,同时保持代码的整洁和可维护性。

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值