28

I am using Spring to inject beans. And I am using some annotations to annotate bean methods (Security, TransactionManagement, ExceptionHanling, Logging). The problem is:

I want to create JUnit test to check if I forgot annotate some methods. But Spring returns $ProxyXXX class without any annotations on methods..

Method[] methods = logic.getClass().getMethods();

  for (Method method : methods) {
     Annotation[] annotations = method.getAnnotations();   // empty array!

How can I get annotations for method or obtain a real class object?

P.S. Spring 2.5.6, JDKDynamicProxy (not CGLib)

skaffman
  • 398,947
  • 96
  • 818
  • 769
Pavel Vyazankin
  • 1,470
  • 6
  • 18
  • 27

4 Answers4

32

Spring's interface-based proxies implement TargetClassAware.

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 6
    Nice! Sorry for outdated comment, I used `AopUtils.getTargetClass(Object)` from "see also" section in the provided link. – iozee Sep 29 '16 at 09:45
24

Or you can just call: AopUtils.getTargetClass(java.lang.Object) It is a static method call.

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
Korobko Alex
  • 816
  • 1
  • 7
  • 10
22

You can cast the proxied object to get the object and class it acts as a proxy for (see TargetSource):

Advised advised = (Advised) proxy;
Class<?> cls = advised.getTargetSource().getTargetClass();

Generally you should follow the Spring principles and keep obtaining the correct class as unobtrusive as possible. Meaning that as little classes as possible should depend on the Spring Framework APIs (maybe add a ClassLocator and a SpringProxyClassLocator implementation).

Daff
  • 43,734
  • 9
  • 106
  • 120
8

AopUtils.getTargetClass only unwraps one level. Use AopProxyUtils.ultimateTargetClass(instance) instead.

(I'm aware this is an 11 years old question, but it's still coming up high in Google, so it benefits from a new answer)

kaqqao
  • 12,984
  • 10
  • 64
  • 118