提交 f1d2c842 编写于 作者: 无难事者若执's avatar 无难事者若执

feat : id生成框架: 自定义多个同样id生成算法名的选择逻辑

- 如果自定义的 idGenerator中的getAlgorithm()方法提供的算法名在系统中有多个,需要自己使用Spring的`Order`注解去配置优先级。
 取Order最大值覆盖替换,如果Order最大值相等,取类名按字符串字典大小比对后最大值的一个。
上级 f54c45c9
# 通用id生成器设计说明
## 概述
id生成在分布式系统或数据库mybatis等框架中经常会使用到。因为算法的不同生成的结果不同。
对于需要不同算法生成id的场景,需要单独去实现。该项目提供一个idService用来支持不同算法生成对应id的能力。
并支持自定义扩展新算法实现。该项目依赖于spring框架。所以需要使用时需要引入spring boot jar。
## 支持特性
- 指定算法生成
- 支持自定义拓展算法
- 项目引入包, spring自动配置
- 不支持算法抛错处理
- 支持配置默认算法
## 使用:
1. 项目引入:
```xml
<dependencies>
<dependency>
<groupId>com.kongxiang</groupId>
<artifactId>kongxiang-spring</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
2. 使用 `idService` 生成id
```java
@Component
public class A{
@Autowired
private IdService idService ;
public void useMethod(){
String id = idService.generate();// 默认 uuid
String id1 = idService.generate("uuid");// 指定
Set<String> supports = idService.supports();// 获取支持的算法列表
}
}
```
3. 拓展自定义算法和使用自定义覆盖
- 3.1 : 继承`com.kx.utils.id.IdGenerator` 编写自己的代码生成器,其中getAlgorithm()方法,提供算法名。
- 3.2 : spring 启动时自动加载您定义的生成器类。
- 3.3 : 如果自定义的 idGenerator中的getAlgorithm()方法提供的算法名在系统中有多个,
需要自己使用Spring的`Order`注解去配置优先级。
取Order最大值覆盖替换,如果Order最大值相等,取类名按字符串字典大小比对后最大值的一个。
4. 修改默认算法,通过generate()方法查询的就是修改后的算法,默认使用`uuid`
```java
/**
* 本地机器uuid id 生成器
* @author kongxiang
*/
@Component
public class LocalUuidGenerator implements IdGenerator {
@Override
public String generate() {
return UUID.randomUUID().toString().replace("-","");
}
@Override
public String getAlgorithm() {
return "uuid";
}
}
```
\ No newline at end of file
......@@ -2,16 +2,16 @@ package com.kx.utils.id;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* id算法注册器
* @author kongxiang
......@@ -30,9 +30,49 @@ public class IdAlgorithmRegister {
@PostConstruct
public void init(){
if (idGeneratorList!= null ){
idGeneratorList.forEach(idGenerator -> {
algorithmMap.put(idGenerator.getAlgorithm(),idGenerator);
log.info(">> Load id generator successful -- : algorithm : [ {} ] ", idGenerator.getAlgorithm());
// name , order, index --> 只保存order最大时的 name对应的idgen
Map<String,Integer[]> nameOrderMap = new LinkedHashMap<>(idGeneratorList.size());
for (int i = 0; i < idGeneratorList.size(); i++) {
IdGenerator idGenerator = idGeneratorList.get(i);
String algorithm = idGenerator.getAlgorithm();
int orderValue = 0;
if (idGenerator.getClass().isAnnotationPresent(Order.class)){
Order order = idGenerator.getClass().getDeclaredAnnotation(Order.class);
orderValue = order.value();
if (StringUtils.isEmpty(orderValue)){
orderValue = 0 ;
}
}
// 选取最大order进行存入
if (!nameOrderMap.containsKey(algorithm)){
Integer[] orderIndexArr = new Integer[2];
orderIndexArr[1] = i;
orderIndexArr[0] = orderValue;
nameOrderMap.put(algorithm,orderIndexArr);
}else {
Integer[] arr = nameOrderMap.get(algorithm);
if (arr[0] < orderValue){
arr[0] = orderValue;// 取较大的order
arr[1] = i; // 更新下表
// nameOrderMap.put(algorithm,arr) ;
}else if (arr[0 ] == orderValue){
// 如果order一致,比较类名的字符串字典大小,取大值
String up = idGeneratorList.get(arr[0]).getClass().getSimpleName();
String thisGen = idGenerator.getClass().getSimpleName();
if (up.compareToIgnoreCase(thisGen) < 0 ){
arr[0] = orderValue;
arr[1] = i ;
}
}
}
}
nameOrderMap.forEach((name,arr) -> {
IdGenerator idGenerator = idGeneratorList.get(arr[1]);
algorithmMap.put(name,idGenerator);
log.info(">> Load id generator successful -- : algorithm : [ {} ] -- order [{}] -- class : [{}] ",name,arr[0] , idGenerator.getClass() );
});
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册