当前位置:   article > 正文

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

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

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

代码实现
  1. package com.cloud.cloud_oj_learn.aspects;
  2. import com.cloud.cloud_oj_common.annotations.GenerateId;
  3. import com.cloud.cloud_oj_common.enums.Keys;
  4. import jakarta.annotation.Resource;
  5. import org.aspectj.lang.JoinPoint;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.aspectj.lang.annotation.Before;
  8. import org.aspectj.lang.reflect.MethodSignature;
  9. import org.springframework.data.redis.core.StringRedisTemplate;
  10. import org.springframework.stereotype.Component;
  11. import java.lang.annotation.Annotation;
  12. import java.lang.reflect.Field;
  13. import java.lang.reflect.Method;
  14. import java.time.LocalDateTime;
  15. import java.time.ZoneOffset;
  16. import java.time.format.DateTimeFormatter;
  17. /**
  18. * Created with IntelliJ IDEA.
  19. * Description:
  20. * User: PG
  21. * Date: 2024-04-16
  22. * Time: 18:49
  23. */
  24. @Aspect
  25. @Component
  26. public class GenerateIdAspect {
  27. @Resource
  28. private StringRedisTemplate stringRedisTemplate;
  29. // 初始时间戳
  30. private static final long BEGIN_TIME = 1640995200L;
  31. // 序列化位数
  32. private static final int BITE = 32;
  33. public Long getNext(String tableName) {
  34. // 1.生成时间戳
  35. LocalDateTime now = LocalDateTime.now();
  36. long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
  37. long timestamp = nowSecond - BEGIN_TIME;
  38. // 2,生成序列化号
  39. String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
  40. long count = stringRedisTemplate.opsForValue().increment(Keys.GENERATE_ID.getKey() + tableName + ":" + date);
  41. // 3.拼接 返回
  42. return Long.valueOf(timestamp << BITE | count);
  43. }
  44. @Before("execution(* com.cloud.cloud_oj_learn.mapper.*.*(..))")
  45. public void before(JoinPoint joinPoint) {
  46. // 获取方法签名
  47. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  48. // 获取方法对象
  49. Method method = methodSignature.getMethod();
  50. // 获取方法参数值数组
  51. Object[] args = joinPoint.getArgs();
  52. // 获取方法注解
  53. Annotation[][] parameterAnnotations = method.getParameterAnnotations();
  54. for (int i = 0; i < parameterAnnotations.length; i++) {
  55. for (Annotation annotation : parameterAnnotations[i]) {
  56. if (annotation instanceof GenerateId) {
  57. try {
  58. // 获取参数对象
  59. Object arg = args[i];
  60. // 获取这个对象的类文件
  61. Class<?> clazz = arg.getClass();
  62. // 获取这个对象的id属性
  63. Field idField = clazz.getDeclaredField("id");
  64. // 设置字段修改权限
  65. idField.setAccessible(true);
  66. // 获取注解上的value
  67. String value = ((GenerateId) annotation).value();
  68. // 获取该value对应的下一个id
  69. Long nextId = getNext(value);
  70. // 判断是否为空, 如果为空就赋值
  71. if (idField.get(arg) == null) {
  72. idField.set(arg, nextId);
  73. }
  74. } catch (NoSuchFieldException | IllegalAccessException e) {
  75. throw new RuntimeException(e);
  76. }
  77. }
  78. }
  79. }
  80. }
  81. }

图示

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/488390
推荐阅读
相关标签
  

闽ICP备14008679号