Сохранять аннотации на прокси CGLIB? - PullRequest
18 голосов
/ 10 ноября 2009

Я пытаюсь создать объект, используя платформу AOP, которая использует CGLIB для создания прокси-объектов. Как ни странно, «расширенный» прокси-объект лишен ЛЮБЫХ аннотаций, которые имел предыдущий класс!

Может кто-нибудь сказать мне, как я могу заставить CGLIB сохранять аннотации на создаваемых им прокси?

Ура! Nirav

Ответы [ 4 ]

15 голосов
/ 08 января 2012

CGLIB создает подклассы данных классов для генерации прокси. Аннотации не сохраняются в подклассах, если это явно не указано в определении аннотации. @ Inherited аннотация используется для этой цели.

Вы можете использовать эту аннотацию в определяемых вами аннотациях и сделать их достижимыми в подклассах следующим образом:

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
5 голосов
/ 10 ноября 2009

Это не проблема с "сохранением" аннотаций. Прокси-серверы CGLIB фактически являются сгенерированными подклассами класса целевого объекта. Эти подклассы могут не иметь аннотаций, но их суперкласс (т.е. ваш собственный класс) все равно будет иметь их. Любой используемый вами код, отражающий аннотации, должен иметь возможность просматривать иерархию классов в поисках аннотаций.

3 голосов
/ 02 мая 2014

Cglib не способен сохранять аннотации без изменения своей внутренней реализации. Это, однако, довольно сложно, и поверьте мне, я пытался. Моя измененная версия, которую я наконец-то придумал, была настолько сложной, что я решил реализовать Byte Buddy , еще одну библиотеку генерации кода, которая способна на такую ​​функциональность.

Вот пример того, как вы можете создать подкласс, который

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation { }

@MyAnnotation
class MyClass { }

assertThat(new ByteBuddy()
  .subclass(Object.class)
  .attribute(TypeAttributeAppender.ForSuperType.INSTANCE)
  .make()
  .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
  .getLoaded()
  .isAnnotationPresent(MyAnnotation.class), is(true));

Byte Buddy поставляется с обширной полнотекстовой документацией и javadoc, и он вполне расширяем. Надеюсь, вы хорошо используете библиотеку.

3 голосов
/ 15 сентября 2010

Это серьезная проблема (я сам сейчас сталкиваюсь): а) не все фреймворки достаточно умны, чтобы проверять родительские классы б) даже если они достаточно умны, они могут отказаться. Последнее похоже на случай с Guice. FWIW, https://issues.apache.org/jira/browse/WICKET-1130 - это проблема, над которой я работал, когда узнал об этом.

...