共160行
2026-05-08 18:58:31
@NeedUpdateRecord 注解的完整实现:@NeedUpdateRecord 注解原理详解@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedUpdateRecord {
String modal() default "";
}作用: 标记需要记录操作日志的方法,modal 参数指定业务模块类型(如 "activity")。
@Aspect
@Component
public class UpdateRecordAspect {
@Autowired
private ActivityUpdateRecordService activityUpdateRecordService;
// 方法执行成功后触发
@AfterReturning(value = "@annotation(needUpdateRecord)&&args(po,..)")
public void doUpdateRecord(NeedUpdateRecord needUpdateRecord, ZyActivityPO po) {
if (ModalEnum.Activity.getCode().equals(needUpdateRecord.modal())) {
activityUpdateRecordService.saveRecordByActivity(po);
}
}
}关键点:
@AfterReturning - 在目标方法成功返回后执行@annotation(needUpdateRecord) - 拦截带有 @NeedUpdateRecord 注解的方法args(po,..) - 提取第一个参数(ZyActivityPO)modal 类型调用对应的记录服务@Transactional(rollbackFor = Exception.class)
@NeedUpdateRecord(modal = "activity") // ← 标记需要记录日志
public void savePO(ZyActivityPO po, List<Long> activityRuleIdList) {
this.savePO(po); // 保存活动
// 删除旧的活动规则关联
Optional.ofNullable(po.getId())
.map(zyRelationActivityActivityRuleDAO::findByZyActivityId)
.ifPresent(zyRelationActivityActivityRuleDAO::deleteInBatch);
// 创建新的活动规则关联
activityRuleIdList.stream()
.map(x -> new ZyRelationActivityActivityRulePO(po.getId(), x))
.forEach(zyRelationActivityActivityRuleDAO::save);
}@Override
public void saveRecordByActivity(ZyActivityPO po) {
// 查询活动的详细信息(包含关联数据)
ZyActivityPageParams params = new ZyActivityPageParams();
params.setId(po.getId());
params.setPageNum(1);
params.setPageSize(1);
ZyActivityPageVO contentVO = activityService.page(params).getList().get(0);
// 只有非草稿状态才记录
if (ZyActivityStatusEnum.DRAFT.getId() != po.getStatus()) {
zyActivityUpdateRecordDAO.save(
new ZyActivityUpdateRecordPO(
po.getId(),
contentVO, // 保存活动的完整快照(JSON格式)
myRequestUtil.fixGetLoginUid() // 操作人ID
)
);
}
}用户调用 add() 或 update()
↓
通过 Spring 代理调用 savePO()
├─ @Transactional 开启事务
└─ 执行业务逻辑
├─ 保存活动数据
├─ 更新活动规则关联
└─ 方法成功返回
↓
@AfterReturning 切面触发
├─ 检查 modal 类型("activity")
└─ 调用 saveRecordByActivity()
├─ 查询活动完整信息
├─ 生成 JSON 快照
└─ 保存到 zy_activity_update_record 表
modal 参数支持不同业务模块// ❌ 错误:this 调用,AOP 不生效
this.savePO(po, params.getActivityRuleIdList());
// ✅ 正确:通过 Spring 容器获取代理对象
SpringUtil.getBean(ActivityServiceImpl.class).savePO(po, params.getActivityRuleIdList());这就是为什么你的代码使用了 SpringUtil.getBean() 而不是 this 调用的原因!