Просмотр исходного кода

新增雪花ID配置,修改默认网络信息获取.

nieqiurong 1 год назад
Родитель
Сommit
8edd3e56ff

+ 10 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisSqlSessionFactoryBuilder.java

@@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
 import com.baomidou.mybatisplus.core.injector.SqlRunnerInjector;
 import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.NetUtils;
 import org.apache.ibatis.exceptions.ExceptionFactory;
 import org.apache.ibatis.executor.ErrorContext;
 import org.apache.ibatis.session.Configuration;
@@ -30,6 +31,7 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.net.InetAddress;
 import java.util.Properties;
 
 /**
@@ -81,7 +83,14 @@ public class MybatisSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder {
 
         final IdentifierGenerator identifierGenerator;
         if (null == globalConfig.getIdentifierGenerator()) {
-            identifierGenerator = DefaultIdentifierGenerator.getInstance();
+            GlobalConfig.Sequence sequence = globalConfig.getSequence();
+            if (sequence.getWorkerId() != null && sequence.getDatacenterId() != null) {
+                identifierGenerator = new DefaultIdentifierGenerator(sequence.getWorkerId(), sequence.getDatacenterId());
+            } else {
+                NetUtils.NetProperties netProperties = new NetUtils.NetProperties(sequence.getPreferredNetworks(), sequence.getIgnoredInterfaces());
+                InetAddress inetAddress = new NetUtils(netProperties).findFirstNonLoopbackAddress();
+                identifierGenerator = new DefaultIdentifierGenerator(inetAddress);
+            }
             globalConfig.setIdentifierGenerator(identifierGenerator);
         } else {
             identifierGenerator = globalConfig.getIdentifierGenerator();

+ 45 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/config/GlobalConfig.java

@@ -27,10 +27,13 @@ import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
 import com.baomidou.mybatisplus.core.injector.ISqlInjector;
 import com.baomidou.mybatisplus.core.mapper.Mapper;
 import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
 import lombok.experimental.Accessors;
 import org.apache.ibatis.session.SqlSessionFactory;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentSkipListSet;
@@ -92,6 +95,10 @@ public class GlobalConfig implements Serializable {
      * 主键生成器
      */
     private IdentifierGenerator identifierGenerator;
+    /**
+     * 数据库相关配置
+     */
+    private Sequence sequence = new Sequence();
 
     @Data
     public static class DbConfig {
@@ -229,4 +236,42 @@ public class GlobalConfig implements Serializable {
             return selectStrategy == null ? whereStrategy : selectStrategy;
         }
     }
+
+    /**
+     * 雪花ID配置
+     * <p>
+     * 1. 手动指定{@link #workerId} 和 {@link #datacenterId}
+     * </p>
+     * <p>
+     * 2. 基于网卡信息和进程PID计算 {@link #workerId} 和 {@link #datacenterId}
+     * </p>
+     *
+     * @since 3.5.7
+     */
+    @Getter
+    @Setter
+    public static class Sequence {
+
+        /**
+         * 工作机器 ID
+         */
+        private Long workerId;
+
+        /**
+         * 数据标识 ID 部分
+         */
+        private Long datacenterId;
+
+        /**
+         * 首选网络地址 (例如: 192.168.1,支持正则)
+         */
+        private List<String> preferredNetworks = new ArrayList<>();
+
+        /**
+         * 忽略网卡(例如:eth0,,支持正则)
+         */
+        private List<String> ignoredInterfaces = new ArrayList<>();
+
+    }
+
 }

+ 122 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/NetUtils.java

@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011-2023, baomidou (jobob@qq.com).
+ *
+ * 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 com.baomidou.mybatisplus.core.toolkit;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * 来源 SpringCloud-Commons {@link org.springframework.cloud.commons.util.InetUtils}.
+ *
+ * @author nieqiurong 2024年4月13日 20:49:47
+ * @since 3.5.7
+ */
+public class NetUtils {
+
+    private static final Log LOG = LogFactory.getLog(NetUtils.class);
+
+    private final NetProperties netProperties;
+
+    public NetUtils(NetProperties netProperties) {
+        this.netProperties = netProperties;
+    }
+
+    public InetAddress findFirstNonLoopbackAddress() {
+        InetAddress result = null;
+        try {
+            for (Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+                 networkInterfaces.hasMoreElements(); ) {
+                NetworkInterface networkInterface = networkInterfaces.nextElement();
+                if (networkInterface.isUp()) {
+                    if (!ignoreInterface(networkInterface.getDisplayName())) {
+                        for (Enumeration<InetAddress> addresses = networkInterface
+                            .getInetAddresses(); addresses.hasMoreElements(); ) {
+                            InetAddress address = addresses.nextElement();
+                            if (address instanceof Inet4Address
+                                && !address.isLoopbackAddress()
+                                && isPreferredAddress(address)) {
+                                result = address;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (IOException exception) {
+            LOG.error("Cannot get first non-loopback address", exception);
+        }
+        if (result != null) {
+            return result;
+        }
+        try {
+            return InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            throw new RuntimeException("Unable to retrieve localhost");
+        }
+    }
+
+    boolean isPreferredAddress(InetAddress address) {
+        final List<String> preferredNetworks = this.netProperties.getPreferredNetworks();
+        if (preferredNetworks.isEmpty()) {
+            return true;
+        }
+        for (String regex : preferredNetworks) {
+            final String hostAddress = address.getHostAddress();
+            if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean ignoreInterface(String interfaceName) {
+        List<String> ignoredInterfaces = this.netProperties.getIgnoredInterfaces();
+        for (String regex : ignoredInterfaces) {
+            if (interfaceName.matches(regex)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class NetProperties {
+
+        /**
+         * 首选网络地址 (例如: 192.168.1,支持正则)
+         */
+        private List<String> preferredNetworks = new ArrayList<>();
+
+        /**
+         * 忽略网卡(例如:eth0,,支持正则)
+         */
+        private List<String> ignoredInterfaces = new ArrayList<>();
+
+    }
+}