将 类 与 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中存在这样的字段,则需要检查:
- 已实现任何接口。如果至少存在一个接口,则增强的 class 可能就是这个接口。 (您可能会发现必须忽略的 cglib 的
Factory
接口。)
- 有超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。
我想测试两个值是否相同 class:
x.getClass.equals(y.getClass)
但是,如果一个(或两个)值实际上属于由 CGLib Enhancer
.
显而易见的解决方案是在 class 名称中搜索 $$EnhancerByCGLIB$$...
,将其删除,然后比较 class 名称的剩余部分(和 classloaders) .有更好的选择吗?
cglib 允许用户设置 NamingStrategy
,这使得替换 EnhancerByCGLIB 标签不可靠,因为 class 可以任意命名。
识别 cglib class 的最可靠方法是检查是否存在字段 CGLIB$BOUND
,该字段已硬编码到库中,因此名称无法更改。如果class中存在这样的字段,则需要检查:
- 已实现任何接口。如果至少存在一个接口,则增强的 class 可能就是这个接口。 (您可能会发现必须忽略的 cglib 的
Factory
接口。) - 有超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。