Parcourir la source

feat: ID生成策略领域开发

seamew il y a 2 ans
Parent
commit
59bce49185

+ 12 - 0
lottery-common/src/main/java/com/seamew/lottery/common/Constants.java

@@ -234,4 +234,16 @@ public class Constants {
             return info;
         }
     }
+
+    /**
+     * Ids 生成策略枚举
+     */
+    public enum Ids {
+        /** 雪花算法 */
+        SnowFlake,
+        /** 日期算法 */
+        ShortCode,
+        /** 随机算法 */
+        RandomNumeric;
+    }
 }

+ 4 - 0
lottery-domain/pom.xml

@@ -34,6 +34,10 @@
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>com.seamew</groupId>

+ 21 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/IIdGenerator.java

@@ -0,0 +1,21 @@
+package com.seamew.lottery.domain.support.ids;
+
+/**
+ * @Author: seamew
+ * @Title: IIdGenerator
+ * @CreateTime: 2023年02月16日 10:06:00
+ * @Description: 生成ID接口
+ * @Version: 1.0
+ */
+public interface IIdGenerator {
+
+    /**
+     * 获取ID,目前有两种实现方式
+     * 1. 雪花算法,用于生成单号
+     * 2. 日期算法,用于生成活动编号类,特性是生成数字串较短,但指定时间内不能生成太多
+     * 3. 随机算法,用于生成策略ID
+     *
+     * @return ID
+     */
+    long nextId();
+}

+ 44 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/IdContext.java

@@ -0,0 +1,44 @@
+package com.seamew.lottery.domain.support.ids;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.support.ids.annotation.IdMode;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.AnnotationUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author: seamew
+ * @Title: IdContext
+ * @CreateTime: 2023年02月16日 10:56:00
+ * @Description: Id 策略模式上下文配置「在正式的完整的系统架构中,ID 的生成会有单独的服务来完成,其他服务来调用 ID 生成接口即可」
+ * @Version: 1.0
+ */
+@Configuration
+public class IdContext {
+
+    @Resource
+    private List<IIdGenerator> idGeneratorList  = new ArrayList<>();
+
+    /**
+     * 创建 ID 生成策略对象,属于策略设计模式的使用方式
+     *
+     * @return IIdGenerator 实现类
+     */
+    @Bean
+    public Map<Constants.Ids, IIdGenerator> idGenerator() {
+        Map<Constants.Ids, IIdGenerator> idGeneratorMap = new HashMap<>(8);
+        idGeneratorList.forEach(element -> {
+            IdMode idMode = AnnotationUtils.findAnnotation(element.getClass(), IdMode.class);
+            if (idMode != null) {
+                idGeneratorMap.put(idMode.idMode(), element);
+            }
+        });
+        return idGeneratorMap;
+    }
+}

+ 21 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/annotation/IdMode.java

@@ -0,0 +1,21 @@
+package com.seamew.lottery.domain.support.ids.annotation;
+
+import com.seamew.lottery.common.Constants;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Author: seamew
+ * @Title: IdMode
+ * @CreateTime: 2023年02月16日 10:38:00
+ * @Description:
+ * @Version: 1.0
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface IdMode {
+    Constants.Ids idMode();
+}

+ 24 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/policy/RandomNumeric.java

@@ -0,0 +1,24 @@
+package com.seamew.lottery.domain.support.ids.policy;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.support.ids.IIdGenerator;
+import com.seamew.lottery.domain.support.ids.annotation.IdMode;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: seamew
+ * @Title: RandomNumeric
+ * @CreateTime: 2023年02月16日 10:35:00
+ * @Description: 随机算法,用于生成策略ID
+ * @Version: 1.0
+ */
+@Component
+@IdMode(idMode = Constants.Ids.RandomNumeric)
+public class RandomNumeric implements IIdGenerator {
+
+    @Override
+    public synchronized long nextId() {
+        return Long.parseLong(RandomStringUtils.randomNumeric(11));
+    }
+}

+ 40 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/policy/ShortCode.java

@@ -0,0 +1,40 @@
+package com.seamew.lottery.domain.support.ids.policy;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.support.ids.IIdGenerator;
+import com.seamew.lottery.domain.support.ids.annotation.IdMode;
+import org.springframework.stereotype.Component;
+
+import java.util.Calendar;
+import java.util.Random;
+
+/**
+ * @Author: seamew
+ * @Title: ShortCode
+ * @CreateTime: 2023年02月16日 10:31:00
+ * @Description: 短码生成策略,仅支持很小的调用量,用于生成活动配置类编号,保证全局唯一
+ * @Version: 1.0
+ */
+@Component
+@IdMode(idMode = Constants.Ids.ShortCode)
+public class ShortCode implements IIdGenerator {
+
+    @Override
+    public synchronized long nextId() {
+        Calendar calendar = Calendar.getInstance();
+        int year = calendar.get(Calendar.YEAR);
+        int week = calendar.get(Calendar.WEEK_OF_YEAR);
+        int day = calendar.get(Calendar.DAY_OF_WEEK);
+        int hour = calendar.get(Calendar.HOUR_OF_DAY);
+
+        // 打乱排序:2020年为准 + 小时 + 周期 + 日 + 三位随机数
+        StringBuilder idStr = new StringBuilder();
+        idStr.append(year - 2020);
+        idStr.append(hour);
+        idStr.append(String.format("%02d", week));
+        idStr.append(day);
+        idStr.append(String.format("%03d", new Random().nextInt(1000)));
+
+        return Long.parseLong(idStr.toString());
+    }
+}

+ 45 - 0
lottery-domain/src/main/java/com/seamew/lottery/domain/support/ids/policy/SnowFlake.java

@@ -0,0 +1,45 @@
+package com.seamew.lottery.domain.support.ids.policy;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.net.NetUtil;
+import cn.hutool.core.util.IdUtil;
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.support.ids.IIdGenerator;
+import com.seamew.lottery.domain.support.ids.annotation.IdMode;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @Author: seamew
+ * @Title: SnowFlake
+ * @CreateTime: 2023年02月16日 10:08:00
+ * @Description: 15位雪花算法推荐
+ * @Version: 1.0
+ */
+@Component
+@IdMode(idMode = Constants.Ids.SnowFlake)
+public class SnowFlake implements IIdGenerator {
+
+    private Snowflake snowflake;
+
+    @PostConstruct
+    public void init() {
+        // 0 ~ 31 位,可以采用配置的方式使用
+        long workerId;
+        try {
+            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
+        } catch (Exception e) {
+            workerId = NetUtil.getLocalhostStr().hashCode();
+        }
+        workerId = workerId >> 16 & 31;
+        long dataCenterId = 1L;
+        snowflake = IdUtil.getSnowflake(workerId, dataCenterId);
+    }
+
+    @Override
+    public synchronized long nextId() {
+        return snowflake.nextId();
+    }
+
+}

+ 36 - 0
lottery-interfaces/src/test/java/com/seamew/lottery/test/domain/SupportTest.java

@@ -0,0 +1,36 @@
+package com.seamew.lottery.test.domain;
+
+import com.seamew.lottery.common.Constants;
+import com.seamew.lottery.domain.support.ids.IIdGenerator;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * @Author: seamew
+ * @Title: SupportTest
+ * @CreateTime: 2023年02月16日 11:16:00
+ * @Description:
+ * @Version: 1.0
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@Slf4j
+public class SupportTest {
+    @Resource
+    private Map<Constants.Ids, IIdGenerator> idGeneratorMap;
+
+    @Test
+    public void test_ids() {
+        log.info("雪花算法策略,生成ID:{}", idGeneratorMap.get(Constants.Ids.SnowFlake).nextId());
+        log.info("日期算法策略,生成ID:{}", idGeneratorMap.get(Constants.Ids.ShortCode).nextId());
+        log.info("随机算法策略,生成ID:{}", idGeneratorMap.get(Constants.Ids.RandomNumeric).nextId());
+    }
+
+
+}