刘光辉
昨天 bb638871a7fb692d80f1b7a758f991dc0879002c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package jnpf.util;
 
/**
 * 网关专用的 {@code jnpf.util.Ip2RegionUtil} 替身(2026-08-11,平台补丁 #15)。
 *
 * <p><b>为什么要有这个类</b>:上游把「IP 归属地工具类」和「它的数据文件」拆在了两个模块里——
 * <ul>
 *   <li>类 {@code jnpf.util.Ip2RegionUtil} 在 <b>jnpf-common-core</b>(gateway 经 jnpf-common-auth 传递依赖到)</li>
 *   <li>它要的 {@code ip2region_v4.xdb}(11MB) + {@code ip2region_v6.xdb}(36MB) 在 <b>jnpf-common-springaop</b></li>
 * </ul>
 * 而 gateway 依赖前者、不依赖后者(springaop 是 servlet 栈 + Sa-Token servlet 版,
 * 与 WebFlux 网关不可同进程,加不得)。于是 jnpf-common-core 的
 * {@code CoreAutoConfiguration.afterPropertiesSet()} 里那句<b>无条件预热调用</b>:
 * <pre>
 *     initUserAgent();
 *     Ip2RegionUtil.getIpRegion(null);   // 传 null、返回值 pop 丢弃,纯粹为了触发类加载
 * </pre>
 * 就会触发原类的 static 块去读那两个不存在的 xdb,每次启动固定刷两条 ERROR:
 * <pre>
 *     ERROR jnpf.util.Ip2RegionUtil : failed to load content from `/ip2region/ip2region_v4.xdb`: ...
 *     ERROR jnpf.util.Ip2RegionUtil : failed to load content from `/ip2region/ip2region_v6.xdb`: ...
 * </pre>
 *
 * <p><b>为什么用替身而不是补数据文件</b>:把 47MB 的 xdb 塞进 gateway 镜像,
 * 只为喂饱一句参数是 {@code null} 的预热调用——gateway 自身根本不解析归属地
 * ({@code AuthFilter} / {@code ReactorUtil} 只取 IP 字符串),归属地解析发生在 cx-platform,
 * 那边有 springaop、xdb 正常加载。镜像刚从 5219MB 压到 762MB,不值当。
 *
 * <p><b>行为与原类在「xdb 缺失」时完全一致</b>(反编译核对过):原类加载失败后
 * {@code SEARCHER_4}/{@code SEARCHER_6} 均为 null,{@code getIpRegion} 走到
 * {@code aconst_null; areturn} 返回 {@code null},{@code getIp2RegionStr} 见 null 原样返回 null。
 * 所以本替身返回 null <b>不是</b>新行为,只是把「返回 null 之前先刷两条 ERROR」这一步省掉了。
 *
 * <p><b>覆盖原理</b>:Spring Boot fat jar 的 {@code LaunchedClassLoader} 里
 * {@code BOOT-INF/classes/} 优先于 {@code BOOT-INF/lib/*.jar},故本类只在 <b>gateway</b> 生效,
 * 其余服务照常使用 jnpf-common-core 里的真实实现。
 *
 * <p><b>回滚</b>:删掉本文件即可(会退回「两条 ERROR + 返回 null」的原状态,功能无差别)。
 * 详见 tasks/jnpf-platform-patches.md #15。
 *
 * @author cx-team
 */
public class Ip2RegionUtil {
 
    /** 与原类在 xdb 缺失时的返回值一致:null。 */
    public static String getIpRegion(String ip) {
        return null;
    }
 
    /** 与原类在 xdb 缺失时的返回值一致:null(原类内部就是 getIpRegion 返回 null 后原样透传)。 */
    public static String getIp2RegionStr(String ip) {
        return null;
    }
}