Kaynağa Gözat

IdGeneratorFactory 优化

MaxKey 5 gün önce
ebeveyn
işleme
a033eea035
13 değiştirilmiş dosya ile 270 ekleme ve 116 silme
  1. 3 3
      maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/scancode/ScanCodeService.java
  2. 0 88
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/IdGenerator.java
  3. 35 2
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/SnowFlakeId.java
  4. 24 0
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/IdGenerator.java
  5. 73 0
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/IdGeneratorFactory.java
  6. 36 0
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/RandomStringGenerator.java
  7. 39 0
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/SnowFlakeIdGenerator.java
  8. 36 0
      maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/UuidStringGenerator.java
  9. 7 7
      maxkey-commons/maxkey-core/src/main/java/org/dromara/maxkey/web/WebContext.java
  10. 3 3
      maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/endpoint/PasskeyAuthenticationEndpoint.java
  11. 4 4
      maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/service/impl/PasskeyServiceImpl.java
  12. 3 3
      maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/util/PasskeyUtils.java
  13. 7 6
      maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/ApplicationAutoConfiguration.java

+ 3 - 3
maxkey-authentications/maxkey-authentication-provider/src/main/java/org/dromara/maxkey/authn/provider/scancode/ScanCodeService.java

@@ -19,7 +19,7 @@ package org.dromara.maxkey.authn.provider.scancode;
 
 import org.dromara.maxkey.authn.session.Session;
 import org.dromara.maxkey.exception.BusinessException;
-import org.dromara.maxkey.id.IdGenerator;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
 import org.dromara.maxkey.persistence.cache.MomentaryService;
 import org.dromara.maxkey.util.TimeJsonUtils;
 import org.slf4j.Logger;
@@ -58,7 +58,7 @@ public class ScanCodeService {
 
 
     @Autowired
-    IdGenerator idGenerator;
+    IdGeneratorFactory idGeneratorFactory;
 
     @Autowired
     MomentaryService momentaryService;
@@ -72,7 +72,7 @@ public class ScanCodeService {
     }
 
     public String createTicket() {
-        String ticket = idGenerator.generate();
+        String ticket = idGeneratorFactory.generate();
         ScanCodeState scanCodeState = new ScanCodeState();
         scanCodeState.setState("unscanned");
 

+ 0 - 88
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/IdGenerator.java

@@ -1,88 +0,0 @@
-/*
- * Copyright [2021] [MaxKey of copyright http://www.maxkey.top]
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- 
-
-package org.dromara.maxkey.id;
-
-import org.dromara.maxkey.util.StringGenerator;
-
-public class IdGenerator {
-
-    String strategy = "uuid";
-
-    int datacenterId;
-    
-    int machineId;
-    
-    SnowFlakeId snowFlakeId = new SnowFlakeId(0,0);
-    
-    StringGenerator stringGenerator = new StringGenerator();
-
-    
-    public String generate(){
-        if(strategy.equalsIgnoreCase("uuid")) {
-            return stringGenerator.uuidGenerate();
-        }else if(strategy.equalsIgnoreCase("SnowFlake")) {
-            return snowFlakeId.nextId()+"";
-        }else {
-            return stringGenerator.randomGenerate();
-        }
-    }
-    
-    
-    public IdGenerator() {
-        super();
-    }
-    
-    public IdGenerator(String strategy) {
-        super();
-        this.strategy = strategy;
-    }
-
-
-    public int getDatacenterId() {
-        return datacenterId;
-    }
-
-    public void setDatacenterId(int datacenterId) {
-        this.datacenterId = datacenterId;
-    }
-
-    public int getMachineId() {
-        return machineId;
-    }
-
-    public void setMachineId(int machineId) {
-        this.machineId = machineId;
-    }
-
-    public SnowFlakeId getSnowFlakeId() {
-        return snowFlakeId;
-    }
-
-    public void setSnowFlakeId(SnowFlakeId snowFlakeId) {
-        this.snowFlakeId = snowFlakeId;
-    }
-
-    public StringGenerator getStringGenerator() {
-        return stringGenerator;
-    }
-
-    public void setStringGenerator(StringGenerator stringGenerator) {
-        this.stringGenerator = stringGenerator;
-    }
-
-}

+ 35 - 2
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/SnowFlakeId.java

@@ -17,8 +17,10 @@
 
 package org.dromara.maxkey.id;
 
+import java.net.NetworkInterface;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.Enumeration;
 
 import org.dromara.maxkey.util.DateUtils;
 
@@ -39,8 +41,8 @@ public class SnowFlakeId {
      * 每一部分占用的位数
      */
     private static final  long SEQUENCE_BIT = 12; //序列号占用的位数
-    private static final  long MACHINE_BIT = 5;   //机器标识占用的位数
-    private static final  long DATACENTER_BIT = 5;//数据中心占用的位数
+    private static final  long MACHINE_BIT = 6;   //机器标识占用的位数
+    private static final  long DATACENTER_BIT = 4;//数据中心占用的位数
 
     /**
      * 每一部分的最大值
@@ -69,6 +71,10 @@ public class SnowFlakeId {
         if (machineId > MAX_MACHINE_NUM || machineId < 0) {
             throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
         }
+        
+        if(machineId == 0) {
+        	machineId =SnowFlakeId.generateMacMachineId();
+        }
         this.datacenterId = datacenterId;
         this.machineId = machineId;
     }
@@ -158,6 +164,33 @@ public class SnowFlakeId {
         return snowFlakeIdParse;
     }
 
+    /**
+     * 基于本机 MAC 地址末段 生成唯一的 Machine ID
+     */
+    public static long generateMacMachineId() {
+        long macSegment = 0L;
+        // 获取本机非回环、非虚拟网卡的 MAC 地址最后一段
+        try {
+            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+            while (interfaces.hasMoreElements()) {
+                NetworkInterface iface = interfaces.nextElement();
+                // 过滤掉无效接口
+                if (iface.isLoopback() || iface.isVirtual() || !iface.isUp()) continue;
+
+                byte[] mac = iface.getHardwareAddress();
+                if (mac != null && mac.length > 0) {
+                    // 提取最后一个字节并转换为无符号整数 (0 ~ 255)
+                    macSegment = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
+                    break; // 找到第一个有效网卡即可退出
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("获取本机 MAC 地址失败: " + e.getMessage());
+        }
+        // 保证结果为非负数,并对最大值取模
+        return (macSegment & 0x7FFFFFFF) % (MAX_MACHINE_NUM + 1);
+    }
+    
     private static Date fromatTime(long date) {
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(date);

+ 24 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/IdGenerator.java

@@ -0,0 +1,24 @@
+/*
+ * Copyright [2026] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.dromara.maxkey.id.generator;
+
+public interface IdGenerator {
+    
+    public String generate();
+    
+}

+ 73 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/IdGeneratorFactory.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright [2026] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.dromara.maxkey.id.generator;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.dromara.maxkey.id.generator.impl.RandomStringGenerator;
+import org.dromara.maxkey.id.generator.impl.SnowFlakeIdGenerator;
+import org.dromara.maxkey.id.generator.impl.UuidStringGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IdGeneratorFactory {
+	private static final  Logger logger = LoggerFactory.getLogger(IdGeneratorFactory.class);
+	
+	static ConcurrentMap<String, IdGenerator> idGeneratorMap = new ConcurrentHashMap<>();
+    
+    public static class GeneratorStrategy {
+        public static final String UUID         = "uuid";
+        public static final String RANDOM       = "random";
+        public static final String SNOWFLAKE    = "snowflake";
+    }
+    
+    String strategy = GeneratorStrategy.SNOWFLAKE;
+
+    static {
+        register(GeneratorStrategy.UUID         , new UuidStringGenerator());
+        register(GeneratorStrategy.RANDOM       , new RandomStringGenerator());
+        register(GeneratorStrategy.SNOWFLAKE    , new SnowFlakeIdGenerator());
+    }
+    
+    public static void register(String strategy, IdGenerator generator) {
+        strategy = strategy.toLowerCase();
+        idGeneratorMap.put(strategy, generator);
+        logger.debug( "Register IdGenerator strategy {} -> {}", strategy, generator.getClass().getName() );
+    }
+   
+    public String generate() {
+        return this.generate(strategy);
+    }
+    
+    public String generate(String strategy){
+        if(idGeneratorMap.containsKey(strategy.toLowerCase())) {
+            return idGeneratorMap.get(strategy.toLowerCase()).generate();
+        }
+        return idGeneratorMap.get(GeneratorStrategy.RANDOM).generate();
+    }
+    
+    public IdGeneratorFactory() {
+        super();
+    }
+    
+    public IdGeneratorFactory(String strategy) {
+        super();
+        this.strategy = strategy.toLowerCase();
+    }
+}

+ 36 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/RandomStringGenerator.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright [2026] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.dromara.maxkey.id.generator.impl;
+
+import org.dromara.maxkey.util.StringGenerator;
+import org.dromara.maxkey.id.generator.IdGenerator;
+
+public class RandomStringGenerator implements IdGenerator{
+
+    StringGenerator stringGenerator = new StringGenerator();
+
+    public String generate(){
+         return stringGenerator.randomGenerate();
+    }
+    
+    
+    public RandomStringGenerator() {
+        super();
+    }
+
+}

+ 39 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/SnowFlakeIdGenerator.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright [2026] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.dromara.maxkey.id.generator.impl;
+
+import org.dromara.maxkey.id.SnowFlakeId;
+import org.dromara.maxkey.id.generator.IdGenerator;
+
+public class SnowFlakeIdGenerator implements IdGenerator{
+
+    SnowFlakeId snowFlakeId = new SnowFlakeId(0,0);
+
+    public String generate(){
+      return snowFlakeId.nextId() + "";
+    }
+    
+    public SnowFlakeIdGenerator() {
+    	super();
+    }
+    
+    public SnowFlakeIdGenerator(SnowFlakeId snowFlakeId) {
+        super();
+        this.snowFlakeId = snowFlakeId;
+    }
+}

+ 36 - 0
maxkey-commons/maxkey-common/src/main/java/org/dromara/maxkey/id/generator/impl/UuidStringGenerator.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright [2026] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.dromara.maxkey.id.generator.impl;
+
+import org.dromara.maxkey.util.StringGenerator;
+import org.dromara.maxkey.id.generator.IdGenerator;
+
+public class UuidStringGenerator implements IdGenerator{
+
+    StringGenerator stringGenerator = new StringGenerator();
+
+    public String generate(){
+       return stringGenerator.uuidGenerate();
+
+    }
+    
+    public UuidStringGenerator() {
+        super();
+    }
+    
+}

+ 7 - 7
maxkey-commons/maxkey-core/src/main/java/org/dromara/maxkey/web/WebContext.java

@@ -28,7 +28,7 @@ import java.util.Map;
 import org.apache.commons.logging.LogFactory;
 import org.dromara.maxkey.configuration.ApplicationConfig;
 import org.dromara.maxkey.entity.Institutions;
-import org.dromara.maxkey.id.IdGenerator;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
 import org.dromara.maxkey.util.DateUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -72,7 +72,7 @@ public final class WebContext {
     
     public static ArrayList<String> logoutAttributeNameList = new ArrayList<String>();
     
-    public static IdGenerator idGenerator;
+    public static IdGeneratorFactory idGeneratorFactory;
     
     static {
         sessionAttributeNameList.add(WebConstants.AUTHENTICATION);
@@ -519,14 +519,14 @@ public final class WebContext {
      * @return String
      */
     public static String genId() {
-        if(idGenerator == null) {
-            idGenerator = new IdGenerator();
+        if(idGeneratorFactory == null) {
+        	idGeneratorFactory = new IdGeneratorFactory();
         }
-        return idGenerator.generate();
+        return idGeneratorFactory.generate();
     }
 
-    public static void setIdGenerator(IdGenerator idGenerator) {
-        WebContext.idGenerator = idGenerator;
+    public static void setIdGeneratorFactory(IdGeneratorFactory idGeneratorFactory) {
+        WebContext.idGeneratorFactory = idGeneratorFactory;
     }
 
     public static ModelAndView redirect(String redirectUrl) {

+ 3 - 3
maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/endpoint/PasskeyAuthenticationEndpoint.java

@@ -19,7 +19,7 @@ package org.dromara.maxkey.passkey.endpoint;
 import org.dromara.maxkey.passkey.manager.PasskeyManager;
 import org.dromara.maxkey.entity.Message;
 import org.dromara.maxkey.entity.idm.UserInfo;
-import org.dromara.maxkey.id.IdGenerator;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
 import org.dromara.maxkey.persistence.service.UserInfoService;
 import org.dromara.maxkey.authn.web.AuthorizationUtils;
 import org.dromara.maxkey.authn.session.Session;
@@ -114,8 +114,8 @@ public class PasskeyAuthenticationEndpoint {
             authenticationToken.setDetails(new WebAuthenticationDetails(WebContext.getRequest()));
             
             // 创建会话
-            IdGenerator idGenerator = new IdGenerator();
-            String sessionId = idGenerator.generate();
+            IdGeneratorFactory idGeneratorFactory = new IdGeneratorFactory();
+            String sessionId = idGeneratorFactory.generate();
             Session session = new Session(sessionId, authenticationToken);
             session.setLastAccessTime(LocalDateTime.now());
             

+ 4 - 4
maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/service/impl/PasskeyServiceImpl.java

@@ -18,7 +18,7 @@ package org.dromara.maxkey.passkey.service.impl;
 
 import org.dromara.maxkey.passkey.service.PasskeyService;
 import org.dromara.maxkey.entity.passkey.UserPasskey;
-import org.dromara.maxkey.id.IdGenerator;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
 import org.dromara.maxkey.entity.passkey.PasskeyChallenge;
 import org.dromara.maxkey.passkey.config.PasskeyProperties;
 import org.dromara.maxkey.persistence.service.UserPasskeyService;
@@ -86,7 +86,7 @@ public class PasskeyServiceImpl implements PasskeyService {
     private PasskeyChallengeService passkeyChallengeService;
     
     private final SecureRandom secureRandom = new SecureRandom();
-    private final IdGenerator idGenerator = new IdGenerator();
+    private final IdGeneratorFactory idGeneratorFactory = new IdGeneratorFactory();
     
     @Override
     public Map<String, Object> generateRegistrationOptions(String userId, String username, String displayName) {
@@ -357,7 +357,7 @@ public class PasskeyServiceImpl implements PasskeyService {
      */
     private UserPasskey createUserPasskey(String userId, String credentialIdBase64, RegistrationData registrationData) {
         UserPasskey userPasskey = new UserPasskey();
-        userPasskey.setId(idGenerator.generate());
+        userPasskey.setId(idGeneratorFactory.generate());
         userPasskey.setUserId(userId);
         userPasskey.setCredentialId(credentialIdBase64);
         
@@ -396,7 +396,7 @@ public class PasskeyServiceImpl implements PasskeyService {
             String challengeBase64 = Base64.encodeBase64URLSafeString(challenge);
             
             // 保存挑战信息 - 仅支持无用户名登录
-            String challengeId = new IdGenerator().generate();
+            String challengeId = new IdGeneratorFactory().generate();
             PasskeyChallenge passkeyChallenge = new PasskeyChallenge(challengeId, challengeBase64, "AUTHENTICATION");
             passkeyChallenge.setUserId(null); // 无用户名登录,userId 设为 null
             passkeyChallenge.setInstId("1");

+ 3 - 3
maxkey-starter/maxkey-starter-passkey/src/main/java/org/dromara/maxkey/passkey/util/PasskeyUtils.java

@@ -27,7 +27,7 @@ import com.webauthn4j.server.ServerProperty;
 import org.apache.commons.codec.binary.Base64;
 import org.dromara.maxkey.entity.passkey.PasskeyChallenge;
 import org.dromara.maxkey.entity.passkey.UserPasskey;
-import org.dromara.maxkey.id.IdGenerator;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
 import org.dromara.maxkey.passkey.config.PasskeyProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,7 +45,7 @@ public class PasskeyUtils {
     private static final Logger logger = LoggerFactory.getLogger(PasskeyUtils.class);
     private static final ObjectMapper objectMapper = new ObjectMapper();
     private static final SecureRandom secureRandom = new SecureRandom();
-    private static final IdGenerator idGenerator = new IdGenerator();
+    private static final IdGeneratorFactory idGeneratorFactory = new IdGeneratorFactory();
     
     /**
      * 从clientDataJSON中解析并验证origin
@@ -124,7 +124,7 @@ public class PasskeyUtils {
         secureRandom.nextBytes(challenge);
         String challengeBase64 = Base64.encodeBase64URLSafeString(challenge);
         
-        String challengeId = idGenerator.generate();
+        String challengeId = idGeneratorFactory.generate();
         PasskeyChallenge passkeyChallenge = new PasskeyChallenge(challengeId, challengeBase64, challengeType);
         passkeyChallenge.setUserId(userId);
         

+ 7 - 6
maxkey-starter/maxkey-starter-web/src/main/java/org/dromara/maxkey/autoconfigure/ApplicationAutoConfiguration.java

@@ -30,8 +30,9 @@ import org.dromara.maxkey.crypto.password.NoOpPasswordEncoder;
 import org.dromara.maxkey.crypto.password.PasswordReciprocal;
 import org.dromara.maxkey.crypto.password.SM3PasswordEncoder;
 import org.dromara.maxkey.crypto.password.StandardPasswordEncoder;
-import org.dromara.maxkey.id.IdGenerator;
 import org.dromara.maxkey.id.SnowFlakeId;
+import org.dromara.maxkey.id.generator.IdGeneratorFactory;
+import org.dromara.maxkey.id.generator.impl.SnowFlakeIdGenerator;
 import org.dromara.maxkey.persistence.cache.InMemoryMomentaryService;
 import org.dromara.maxkey.persistence.cache.MomentaryService;
 import org.dromara.maxkey.persistence.cache.RedisMomentaryService;
@@ -152,15 +153,15 @@ public class ApplicationAutoConfiguration {
      * @return
      */
     @Bean
-    IdGenerator idGenerator(
+    IdGeneratorFactory idGeneratorFactory(
             @Value("${maxkey.id.strategy:SnowFlake}") String strategy,
             @Value("${maxkey.id.datacenterId:0}") int datacenterId,
             @Value("${maxkey.id.machineId:0}") int machineId) {
-        IdGenerator idGenerator = new IdGenerator(strategy);
+        IdGeneratorFactory idGeneratorFactory = new IdGeneratorFactory(strategy);
         SnowFlakeId snowFlakeId = new SnowFlakeId(datacenterId,machineId);
-        idGenerator.setSnowFlakeId(snowFlakeId);
-        WebContext.setIdGenerator(idGenerator); 
-        return idGenerator;
+        IdGeneratorFactory.register(strategy, new SnowFlakeIdGenerator(snowFlakeId));
+        WebContext.setIdGeneratorFactory(idGeneratorFactory); 
+        return idGeneratorFactory;
     }