2011-08-29 17 views
6

Rozważmy następujący kod:Jak uzyskać wartość argumentu metody poprzez odbicie w Javie?

public void example(String s, int i, @Foo Bar bar) { 
    /* ... */ 
} 

Jestem zainteresowany wartości argumentu z dopiskiem @Foo. Załóżmy, że już się zorientowałem poprzez odbicie (z Method#getParameterAnnotations()), który parametr metody ma adnotację @Foo. (Wiem, że jest to trzeci parametr listy parametrów.)

Jak mogę teraz pobrać wartość bar do dalszego wykorzystania?

+3

Nie rozumiem pytanie. Wartość 'bar' będzie dostępna tylko podczas pracy. Czy chcesz przechwycić połączenia do 'przykladu'? Czy masz na myśli typ danych "Bar"? – home

Odpowiedz

11

Nie możesz. Odbicie nie ma dostępu do zmiennych lokalnych, w tym parametrów metod.

Jeśli chcesz tę funkcjonalność, trzeba przechwycić wywołanie metody, które można zrobić w jeden z kilku sposobów:

  • AOP (AspectJ/wiosennym AOP etc.)
  • proxy (JDK, CGLib etc)

We wszystkich z nich, by zebrać z parametrów wywołania metody, a następnie powiedzieć wywołanie metody do wykonania. Ale nie ma sposobu, aby uzyskać parametry metody poprzez odbicie.

Aktualizacja: oto aspekt próbki, aby można rozpocząć korzystanie walidacji adnotacji oparte o AspectJ

public aspect ValidationAspect { 

    pointcut serviceMethodCall() : execution(public * com.yourcompany.**.*(..)); 

    Object around(final Object[] args) : serviceMethodCall() && args(args){ 
     Signature signature = thisJoinPointStaticPart.getSignature(); 
     if(signature instanceof MethodSignature){ 
      MethodSignature ms = (MethodSignature) signature; 
      Method method = ms.getMethod(); 
      Annotation[][] parameterAnnotations = 
       method.getParameterAnnotations(); 
      String[] parameterNames = ms.getParameterNames(); 
      for(int i = 0; i < parameterAnnotations.length; i++){ 
       Annotation[] annotations = parameterAnnotations[i]; 
       validateParameter(parameterNames[i], args[i],annotations); 
      } 
     } 
     return proceed(args); 
    } 

    private void validateParameter(String paramName, Object object, 
     Annotation[] annotations){ 

     // validate object against the annotations 
     // throw a RuntimeException if validation fails 
    } 

} 
+0

Używam już AspectJ, ale nie znalazłem sposobu, aby to zrobić. Było to wcześniejsze pytanie: http://stackoverflow.com/questions/7228590/how-to-check-if-a-parameter-of-turrent-method-has-an-annotation-and-retrieve – soc

+0

@soc OK, zobacz moją aktualizację na początek, kup [AspectJ w akcji] (http://www.manning.com/laddad2/), aby naprawdę nauczyć się jak to zrobić (lub zadawać pytania na [liście użytkowników AspectJ] (http: // /www.eclipse.org/aspectj/userlists.php) –

+0

Hej, dziękuję! :-) Już kupiłem książkę, ale starałem się umieścić wszystko w podpisach meczów, które nie działały ... – soc

Powiązane problemy