将 类 与 CGLib 增强功能进行比较

Comparing classes up to CGLib enhancement

我想测试两个值是否相同 class:

x.getClass.equals(y.getClass)

但是,如果一个(或两个)值实际上属于由 CGLib Enhancer.

构造的 class,则此比较应该成功

显而易见的解决方案是在 class 名称中搜索 $$EnhancerByCGLIB$$...,将其删除,然后比较 class 名称的剩余部分(和 classloaders) .有更好的选择吗?

cglib 允许用户设置 NamingStrategy,这使得替换 EnhancerByCGLIB 标签不可靠,因为 class 可以任意命名。

识别 cglib class 的最可靠方法是检查是否存在字段 CGLIB$BOUND,该字段已硬编码到库中,因此名称无法更改。如果class中存在这样的字段,则需要检查:

  1. 已实现任何接口。如果至少存在一个接口,则增强的 class 可能就是这个接口。 (您可能会发现必须忽略的 cglib 的 Factory 接口。)
  2. 有超class不是java.lang.Object。就算是增强了一个接口,明明有超class定义的

作为检测算法的近似值,您可以使用:

static Class<?> original(Class<?> type) {
  try {
    type.getDeclaredField("CGLIB$BOUND");
    if (type.getSuperclass() != Object.class) {
      return type.getSuperclass();
    }
    for (Class<?> iFace : type.getInterfaces()) {
      if (iFace != Factory.class) {
        return iFace;
      }
    }
    return Object.class;
  } catch (NoSuchFieldException ignored) {
    return type;
  }
}

请注意,cglib 允许为 classes 生成代理,这些代理还实现了多个接口,其中上述展开将 return 超级 class。