2009-11-10 15 views
17

Je tente de créer un objet en utilisant un framework AOP qui utilise CGLIB pour créer des objets proxy. Curieusement, l'objet proxy "enhanced" est dépourvu de toute annotation de la classe précédente!Conserver les annotations sur les proxies CGLIB?

Quelqu'un peut-il me dire comment faire pour que CGLIB conserve les annotations sur les proxies qu'il crée?

À la votre! Nirav

+0

Est-ce que l'annotation @Inherited a résolu le problème? Si oui, vous pouvez envisager d'approuver la réponse. Merci. – noego

+0

'@ Inherited' ne résout pas le problème (je l'ai essayé moi-même). Personnellement, j'utilisais un projet Spring et j'ai résolu le problème en utilisant la classe utilitaire AnnotationUtils, donc vous pouvez voir [ici] (https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main /java/org/springframework/core/annotation/AnnotationUtils.java) comment cela fonctionne. – Alessio

Répondre

5

Ce n'est pas un problème de "conserver" les annotations. Les proxys CGLIB sont en fait des sous-classes de la classe de l'objet cible. Ces sous-classes peuvent ne pas avoir d'annotations, mais leur superclasse (c'est-à-dire votre propre classe) les aura toujours. Tout code reflétant les annotations que vous utilisez doit pouvoir remonter dans la hiérarchie des classes pour rechercher des annotations.

3

C'est un problème valide (je suis en train de le faire maintenant) car a) tous les frameworks ne sont pas assez intelligents pour inspecter les classes parentes b) même s'ils sont assez intelligents, ils peuvent choisir de ne pas. Ce dernier semble être le cas avec Guice. FWIW, https://issues.apache.org/jira/browse/WICKET-1130 est le problème sur lequel je travaillais lorsque j'ai découvert cela.

15

CGLIB crée des sous-classes de classes données pour générer des proxys. Les annotations ne sont pas conservées dans les sous-classes, sauf si elles sont explicitement spécifiées dans la définition d'annotation. @Inherited L'annotation est utilisée à cette fin.

Vous pouvez utiliser cette annotation dans les annotations que vous définissez, et de les rendre accessibles en sous-classes, comme suit:

@Inherited 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface MyAnnotation { 
} 
+0

J'ai ce problème, et il ne semble pas que votre correctif fonctionne. –

+0

@Inherited a travaillé pour moi. Merci –

+0

@Inherited ne fonctionne que lorsque la cible de l'annotation est une classe - les méthodes de votre proxy de sous-classe n'ont toujours pas les annotations. – Phil

3

Cglib n'est pas capable de conserver des annotations sans modifier sa mise en œuvre interne. C'est cependant assez compliqué et croyez-moi j'ai essayé. Ma version modifiée que j'ai finalement trouvée était cependant si compliquée que j'ai décidé d'implémenter plutôt Byte Buddy, une autre bibliothèque de génération de code qui est capable d'une telle fonctionnalité.

Voici un exemple de la façon dont vous pouvez créer sous-classe qui

@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 copain est livré avec une documentation complète en texte intégral et javadoc et il est tout à fait extensible. J'espère que vous faites bon usage de la bibliothèque.