苍穹外卖Day9公共字段填充枚举类(Enum Class)自定义切面类
·
文章目录
📌 一、公共字段填充核心实现
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);
}
如果内容对您有帮助,请点赞👍、关注❤️、收藏⭐️
创作不易,您的支持是我持续分享的动力!
更多推荐



所有评论(0)