比较类到CGLib增强

时间:2016-11-08 12:33:14

标签: java cglib

我想测试两个值是否具有相同的类:

x.getClass.equals(y.getClass)

但是,如果一个(或两个)值实际上属于由CGLib Enhancer构造的类,则此比较应该成功。

显而易见的解决方案是在类名中搜索$$EnhancerByCGLIB$$...,删除它,然后比较类名(和类加载器)的其余部分。还有更好的选择吗?

1 个答案:

答案 0 :(得分:2)

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

识别cglib类的最可靠方法是检查字段CGLIB$BOUND的存在性,该字段被硬编码到库中,使得名称不能更改。如果类中存在这样的字段,则需要检查是否:

  1. 实现了任何接口。如果至少存在一个接口,则增强类可能是此接口。 (您可能会发现必须忽略的cglib' Factory接口。)
  2. 有一个不是java.lang.Object的超类。即使界面得到增强,显然也有一个超类定义。
  3. 作为检测算法的近似值,您可以使用:

    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允许为也实现多个接口的类生成代理,其中上述展开将返回超类。