5

mam realizacji procesor adnotacji, aby upewnić się, że elementy oznaczone adnotacją są instancjami klasy, która implementuje określony interfejs, czy też zastosowania typów, które realizują pewien interfejs:Jak przetwarzać adnotacje za pomocą @Target (ElementType.TYPE_USE)?

@Documented 
@Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE }) 
@Retention(value = RetentionPolicy.RUNTIME) 
public @interface AuditSubject { 

} 

public interface Auditable { 
    // methods that provide data for writing a log entry... 
} 

public class Report implements Auditable { 

} 

Dla elementy adnotowane, wpis dziennika musi zostać utworzony po wykonaniu metody (przy użyciu AOP). Przykłady:

@CreateLogEntry 
public Result persist(@AuditSubject Report newReport) { 
    // A log entry must be created with the incoming newReport.  
} 

@CreateLogEntry 
public UpdateResult<@AuditSubject Report> update(Report update) { 
    // A log entry must be created with the updated report which is not the same instance as 'update' (cannot use it). 
} 

@CreateLogEntry 
public Result persistBatch(List<@AuditSubject Report> batch) { 
    // A log entry must be created for each element in 'batch' after this method execution. 
} 

Wpisy do dziennika muszą być tworzone pod warunkiem, że raport implementuje funkcję Auditable; jeśli nie, zostanie zgłoszony wyjątek środowiska wykonawczego (Yikes, zapomniałem zaimplementować interfejs!). Tak więc procesor adnotacji pomaga złapać błędy programisty w czasie kompilacji. Do tej pory udało mi się sprawdzić wszystkie zastosowania w parametrach, ale nie w zastosowaniach typu. Odpowiedni kod z procesora adnotacji jest następujący:

@Override 
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
    for (Element annotated : roundEnv.getElementsAnnotatedWith(AuditSubject.class)) { 
     // Only prints elements with ElementKind.PARAMETER)! 
     this.messager.printMessage(Kind.NOTE, TextUtils.replaceParams("annotated: {} ; Kind : {} ; enclosing : {}", annotated, annotated.getKind(), annotated.getEnclosingElement())); 

     if (annotated.getKind() == ElementKind.PARAMETER) { 
      // Code here works as expected, raises errors for annotated parameters of classes that don't implement Auditable. 
     } else if (annotated.getKind() == ElementKind.WHAT_TO_USE) { 
      // What ElementKind do I need to use here? 
     } 
    } 

    return false; 
} 

Tylko adnotacją elementy z rodzaju ElementKind.PARAMETER ujmuje (pierwsza linia w pętli procesu() drukuje tylko jedną linię dla 'newReport') Jak mogę sprawdzić, czy typy z komentarzami wdrażają funkcję Auditable? Nie można używać stałej "ElementKind.TYPE_USE". Nie mogłem znaleźć żadnych istotnych informacji na ten temat. Dziękuję za uwagę.

Odpowiedz

4

Interfejs API przetwarzania adnotacji Java został zaprojektowany, gdy Java obsługuje tylko adnotacje w deklaracjach. Interfejs API obsługuje tylko deklaracje dotyczące odwiedzin, takie jak pola, metody i parametry metody. Nie odwiedza lokalnych deklaracji zmiennych, ani innych adnotacji w treści metody, ani adnotacji typu.

Jeśli chcesz przetwarzać adnotacje typu lub adnotacje w ciałach metod, będziesz musiał napisać swój własny kod, aby rekursować typy lub powtarzać sprawdzanie wierszy kodu w ramach metody.

Alternatywą dla tego jest użycie narzędzia takiego jak Checker Framework. Implementuje własnych użytkowników, dlatego wbudowany na nich procesor adnotacji jest wywoływany dla każdego wystąpienia adnotacji typu.