【在线OJ系统】自定义注解实现分布式ID无感自增

server/2024/10/21 9:45:44/
实现思路

首先自定义参数注解,然后根据AOP思想,找到该注解作用的切点,也就是mapper层对于mapper层的接口在执行前都会执行该aop操作:获取到对于的方法对象,根据方法对象获取参数列表,根据参数列表判断某个参数上是否加有自定义的注解,如果有则读取注解中的value值,并通过传入对象的引用拿到该对象,此时判断该对象的id值是否位空,如果为空则生成全局唯一id并赋值

代码实现
package com.cloud.cloud_oj_learn.aspects;import com.cloud.cloud_oj_common.annotations.GenerateId;
import com.cloud.cloud_oj_common.enums.Keys;
import jakarta.annotation.Resource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;/*** Created with IntelliJ IDEA.* Description:* User: PG* Date: 2024-04-16* Time: 18:49*/
@Aspect
@Component
public class GenerateIdAspect {@Resourceprivate StringRedisTemplate stringRedisTemplate;// 初始时间戳private static final long BEGIN_TIME = 1640995200L;// 序列化位数private static final int BITE = 32;public Long getNext(String tableName) {// 1.生成时间戳LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIME;// 2,生成序列化号String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));long count = stringRedisTemplate.opsForValue().increment(Keys.GENERATE_ID.getKey() + tableName + ":" + date);// 3.拼接  返回return Long.valueOf(timestamp << BITE | count);}@Before("execution(* com.cloud.cloud_oj_learn.mapper.*.*(..))")public void before(JoinPoint joinPoint) {// 获取方法签名MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();// 获取方法对象Method method = methodSignature.getMethod();// 获取方法参数值数组Object[] args = joinPoint.getArgs();// 获取方法注解Annotation[][] parameterAnnotations = method.getParameterAnnotations();for (int i = 0; i < parameterAnnotations.length; i++) {for (Annotation annotation : parameterAnnotations[i]) {if (annotation instanceof GenerateId) {try {// 获取参数对象Object arg = args[i];// 获取这个对象的类文件Class<?> clazz = arg.getClass();// 获取这个对象的id属性Field idField = clazz.getDeclaredField("id");// 设置字段修改权限idField.setAccessible(true);// 获取注解上的value值String value = ((GenerateId) annotation).value();// 获取该value对应的下一个idLong nextId = getNext(value);// 判断是否为空, 如果为空就赋值 if (idField.get(arg) == null) {idField.set(arg, nextId);}} catch (NoSuchFieldException | IllegalAccessException e) {throw new RuntimeException(e);}}}}}}

图示


http://www.ppmy.cn/server/4993.html

相关文章

java表单类爬虫

见代码附件 编写方式1 public static void Posts() throws IOException{// 创建 HTTP POST 请求HttpPost httpPost new HttpPost("http://www.cninfo.com.cn/new/disclosure");// 设置请求头httpPost.setHeader("Content-Type", "application/x-www…

HarmonyOS开发实例:【分布式新闻客户端】

介绍 本篇Codelab基于栅格布局、设备管理和多端协同&#xff0c;实现一次开发&#xff0c;多端部署的分布式新闻客户端页面。主要包含以下功能&#xff1a; 展示新闻列表以及左右滑动切换新闻Tab。点击新闻展示新闻详情页。点击新闻详情页底部的分享按钮&#xff0c;发现周边…

Games104 现代游戏引擎3

Sprite Animation 序列帧动画 自由度&#xff08;degrees of freedom&#xff0c;DoF&#xff09;对于刚体而言描述它的运动需要3个位移3个旋转&#xff0c;一共6个自由度 顶点动画&#xff08;per-vertex animation&#xff09;利用网格的顶点来控制运动。此时网格上的每个顶…

客户端动态降级系统

本文字数&#xff1a;4576字 预计阅读时间&#xff1a;20分钟 01 背景 无论是iOS还是Android系统的设备&#xff0c;在线上运行时受硬件、网络环境、代码质量等多方面因素影响&#xff0c;可能会导致性能问题&#xff0c;这一类问题有些在开发阶段是发现不了的。如何在线上始终…

达梦数据库导入导出工具dmfldr

达梦数据库导入导出工具dmfldr 基础信息 OS版本&#xff1a; Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a; DM Database Server 64 V8 DB Version: 0x7000c 03134284132-20240115-215128-200811 dmfldr工具介绍 dmfldr&#xff08;DM Fast Loade…

设计模式代码实战-观察者模式

1、问题描述 小明所在的学校有一个时钟&#xff08;主题&#xff09;&#xff0c;每到整点时&#xff0c;它就会通知所有的学生&#xff08;观察者&#xff09;当前的时间&#xff0c;请你使用观察者模式实现这个时钟通知系统。 注意点&#xff1a;时间从 0 开始&#xff0c;并…

Jackson 2.x 系列【25】Spring Boot 集成之起步依赖、自动配置

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. 起步依赖3. 自动配置3.1 JacksonPrope…

Uni-app中实现数据选择并回传给上个页面的方法

当我们在Uni-app中进行页面间数据传递时&#xff0c;通常会涉及到数据的选择以及回传给上个页面的需求。为了达到这个目的&#xff0c;我们可以利用Uni-app提供的事件机制和页面导航方法来实现。以下是一种实现方式&#xff1a; 数据选择并回传给上个页面的方法 第一步&#…