2009-11-10 6 views
17

Estoy tratando de crear un objeto utilizando un marco AOP que utiliza CGLIB para crear objetos proxy. Por extraño que parezca, el objeto proxy "mejorado" carece de CUALQUIER anotación de la clase anterior.¿Conservar anotaciones en los proxies CGLIB?

¿Alguien puede decirme cómo puedo hacer que CGLIB conserve las anotaciones en los proxies que crea?

¡Salud! Nirav

+0

¿La anotación @herida solucionó el problema? Si es así, puede considerar aprobar la respuesta. Gracias. – noego

+0

'@ Inherited' no resuelve el problema (lo intenté solo). Personalmente, estaba usando un proyecto de Spring y lo resolví utilizando la clase de utilidad AnnotationUtils, por lo que puede ver [aquí] (https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main /java/org/springframework/core/annotation/AnnotationUtils.java) cómo funciona. – Alessio

Respuesta

5

Esto no es un problema con "conservar" las anotaciones. Los proxies CGLIB son en realidad subclases generadas de la clase del objeto objetivo. Estas subclases pueden no tener anotaciones, pero su superclase (es decir, su propia clase) todavía las tendrá. Cualquier código que refleje la anotación que utilice debe poder buscar una copia de seguridad de la jerarquía de clases para buscar anotaciones.

3

Es un problema válido (me estoy encontrando ahora mismo) como a) no todos los marcos son lo suficientemente inteligentes como para inspeccionar las clases padre b) incluso si son lo suficientemente inteligentes, pueden elegir no hacerlo. Este último parece ser el caso con Guice. FWIW, https://issues.apache.org/jira/browse/WICKET-1130 es el problema en el que estaba trabajando cuando descubrí esto.

15

CGLIB crea subclases de clases dadas para generar proxies. Las anotaciones no se conservan en subclases a menos que se especifique explícitamente en la definición de anotación. La anotación @Inherited se usa para este propósito.

Puede utilizar esta anotación en las anotaciones que defina, y hacerlos accesibles en subclases, de la siguiente manera:

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

Tengo este problema y no parece que tu corrección funcione. –

+0

@ Heited trabajó para mí. Gracias –

+0

@ Heredado solo funciona cuando el objetivo de la anotación es una clase: los métodos de proxy de su subclase aún no tienen las anotaciones. – Phil

3

Cglib no es capaz de retener las anotaciones sin cambiar su implementación interna. Sin embargo, esto es bastante complicado y créanme, lo intenté. Sin embargo, mi versión modificada que finalmente se me ocurrió fue tan complicada que decidí implementar Byte Buddy, otra biblioteca de generación de código que es capaz de tal funcionalidad.

Aquí es un ejemplo de cómo se puede crear subclase que

@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 compinche viene con una documentación de texto extenso y javadoc y es muy extensible. Espero que hagas un buen uso de la biblioteca.

Cuestiones relacionadas