2016-11-08 55 views
1

我想测试两个值具有相同的类:比较班达CGLIB增强

x.getClass.equals(y.getClass) 

但是,如果一个(或两个)值实际上属于由CGLIB构造一类这个比较应该会成功Enhancer

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

回答

2

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

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

  1. 有实现的接口。如果至少存在一个接口,则增强类可能是此接口。 (你可能会发现cglib的Factory界面,你必须忽略它。)
  2. 有一个超类不是java.lang.Object。即使增强了接口,显然也有一个超类定义。

至于检测算法的逼近,你可以因此使用:

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