📌 一、公共字段填充核心实现

1. 自定义注解 @AutoFill

  • 作用:标识需进行公共字段自动填充的方法
  • 关键元注解
    • @Target(ElementType.METHOD) → 限定注解仅能标注在方法上(如 public void test() {}
    • @Retention(RetentionPolicy.RUNTIME) → 注解在运行时可通过反射获取
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    // 使用枚举限定操作类型
    OperationType value(); 
    
    // 扩展属性:指定字段前缀(默认"common_")
    String prefix() default "common_";
}

2. 枚举类(Enum Class)

  • 典型场景:表示操作类型、状态码、选项等具有固定取值集合的字段
  • 核心优势:确保变量仅从预定义常量中取值,避免无效值
public enum OperationType {
    INSERT(1, "插入操作"),
    UPDATE(2, "更新操作"),
    BATCH_UPDATE(3, "批量更新");
    
    private final int code;
    private final String desc;
    
    // 枚举构造器+getter方法
}

3. 注解属性定义

  • 语法规则返回类型 属性名();
  • 示例OperationType value(); → 在 @AutoFill 注解中定义名为 value 的属性
// 获取方法上的注解
AutoFill autoFill = method.getAnnotation(AutoFill.class);

// 获取注解属性
String prefix = autoFill.prefix();
OperationType opType = autoFill.value();

⚙️ 二、切面类实现自动填充

1. 核心注解

  • @Component → 声明为 Spring 管理的 Bean
  • @Aspect → 标识为切面类(定义AOP逻辑)
  • @Slf4j → 简化日志输出(记录填充过程/异常)
@Around("autoFillPointCut()")
public Object autoFill(ProceedingJoinPoint joinPoint) throws Throwable {
    // 1. 获取当前操作用户(ThreadLocal方案)
    Long currentUserId = UserHolder.getCurrentUserId(); 
    
    // 2. 获取方法参数
    Object[] args = joinPoint.getArgs();
    for (Object arg : args) {
        if (arg instanceof BaseEntity) {
            BaseEntity entity = (BaseEntity) arg;
            
            // 3. 根据操作类型填充字段
            if (opType == OperationType.INSERT) {
                entity.setCreateUser(currentUserId);
                entity.setCreateTime(LocalDateTime.now());
            }
            entity.setUpdateUser(currentUserId);
            entity.setUpdateTime(LocalDateTime.now());
        }
    }
    
    // 4. 执行原方法
    return joinPoint.proceed();
}

2. 精准定位切点(Pointcut)

@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
  • 作用:拦截 Mapper层 所有被 @AutoFill 注解标记的方法
  • 逻辑execution + @annotation 组合确保拦截精准性
// 支持多包路径配置
@Pointcut("(execution(* com.sky..mapper.*.*(..)) || 
          execution(* com.admin..dao.*.*(..))) && 
          @annotation(com.sky.annotation.AutoFill)")

3. 关键概念解析

  • 连接点(JoinPoint):程序执行中的特定点(如方法执行),在Spring AOP中始终代表方法执行
  • 方法签名(MethodSignature):通过 类名+方法名+参数类型 唯一确定被拦截方法,避免误拦截

🌐 附:微信接口调用示例

  • 请求类型: GET
  • 接口地址:
    https://api.weixin.qq.com/sns/jscode2session
public WechatSessionDTO code2session(String code) {
    // 1. 参数校验
    Assert.hasText(code, "微信code不能为空");
    
    // 2. 构建请求参数
    Map<String, String> params = new HashMap<>();
    params.put("appid", wechatConfig.getAppId());
    params.put("secret", wechatConfig.getSecret());
    params.put("js_code", code);
    params.put("grant_type", "authorization_code");
    
    // 3. 发送请求(带超时控制)
    String response = restTemplate.getForObject(API_URL, String.class, params);
    
    // 4. 错误码处理(微信特定错误码转换)
    if(response.contains("errcode")) {
        handleWechatError(response);
    }
    
    return JSON.parseObject(response, WechatSessionDTO.class);
}

如果内容对您有帮助,请点赞👍、关注❤️、收藏⭐️
创作不易,您的支持是我持续分享的动力!
坚持的力量


Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐