2012-01-23 13 views
8

Mam dziwne zachowanie podczas przeglądania za pomocą adnotacji na metodzie należącej do klasy proxy za pośrednictwem CGLIB. Używamy CGLIB na wiosnę i jeśli dodaję adnotację do metody tylko z adnotacją, to działa dobrze (jestem w stanie pobrać adnotacje za pomocą metody getAnnotations() na odpowiednim obiekcie Method). Jeśli dodam adnotację do metody z 2 adnotacjami (bez względu na kolejność adnotacji), getAnnotations() po prostu zwrócę null. Obie adnotacje mają RetentionPolicy.RUNTIME.Adnotacje metody null podczas pośredniczenia za pośrednictwem CGLIB

Przeczytałem, że są pewne problemy z CGLIB, ale to dziwne, że działa po prostu na jedną adnotację i zwraca null, kiedy umieszczam 2 adnotacje.

Wszelkie sugestie?

(Korzystanie Wiosna 3.0.5 i 2.2.2) CGLIB

Dodawanie kodu:

1-ta jest adnotacja:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface Produces { 
    ResultType[] value(); 
} 

2-te adnotacja jest

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface JamonMonitored { 
    String type() default ""; 
    String tag() default ""; 
} 

A blok kodu służy do sprawdzania adnotacji:

Collection<Method> candidates = Collections2.filter(Arrays.asList(executorInstance.getClass().getMethods()), new Predicate<Method>() { 
    @Override 
    public boolean apply(Method input) { 
     return input.getAnnotation(Produces.class) != null; 
    } 
}); 

if (candidates.isEmpty()) { 
    // throws exception 
} 

Jeśli dodaję adnotację do metody z @Produces i @JamonMonitored, getAnnotation(Produces.class) jest zawsze null.

+0

Czy możesz podać kod . to wygląda ciekawie, chciałoby się rzucić okiem. Ale nie słyszałem o takich rzeczach, hnece kod? –

+0

I mam nadzieję, że przeszliście przez ten kawałek - http://stackoverflow.com/questions/1706751/retain-annotations-on-cglib-proxies –

Odpowiedz

14

CGLIB działa poprzez generowanie podklasy klasy obiektu docelowego i ta podklasa wygenerowała metody delegujące do obiektu docelowego. Kiedy używasz odbicia do sprawdzania adnotacji obiektu proxy, pytasz o adnotacje na klasie proxy, a nie na klasie obiektu docelowego.

Wiosna musi wykonać wiele procesów przetwarzania opisów, aby nawigować w poprzek serwerów proxy, klas nadrzędnych, interfejsów i tak dalej. Logika do tego jest hermetyzowana i ujawniona w klasie org.springframework.core.annotation.AnnotationUtils. W twoim przypadku, to brzmi jak chcesz findAnnotation utility method, tj

@Override 
public boolean apply(Method input) { 
    return AnnotationUtils.findAnnotation(input, Produces.class) != null; 
} 
+2

Dzięki, działało idealnie! – manub

1

Innym rozwiązaniem byłoby określić @Inherited w definicji adnotacji. To spowodowałoby pojawienie się adnotacji nawet w podklasach generowanych przez cglib. Oczywiście w niektórych sytuacjach nie chciałbyś, aby twoja adnotacja pojawiała się w "prawdziwych" podklasach, więc nie jest to opcja dla każdego scenariusza, a sposobem na to jest użycie pomocników Springa, jak pokazano przez skaffmana

+0

Wygląda na to, że nie działa to przykro. Chciałbym jednak. –

+0

@ Dziedziczony działa tylko na klasach, a nie na metodach – Phil

Powiązane problemy