cglib позволяет пользователю установить NamingStrategy
, что делает замену метки EnhancerByCGLIB ненадежной, так как класс может быть назван произвольно.
Самый надежный способ идентификации класса cglib - проверить наличие поля CGLIB$BOUND
, которое жестко закодировано в библиотеке, так что имя не может измениться. Если такое поле существует в классе, вам необходимо проверить:
- Имеются любые интерфейсы. Если существует хотя бы один интерфейс, расширенный класс может быть этим интерфейсом. (Возможно, вы найдете интерфейс cglib
Factory
, который вы должны игнорировать.)
- Существует класс супер, который не является
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 позволяет генерировать прокси для классов, которые также реализуют несколько интерфейсов, где выше разворачивание будет возвращать суперкласс.