Procesory adnotacji w czasie kompilacji
Napisz AbstractProcessor do generowania plików źródłowych lub walidowania kodu podczas kompilacji.
Procesory adnotacji w czasie kompilacji to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Czym są procesory adnotacji
Procesory adnotacji (APT — Annotation Processing Tool) działają podczas kompilacji. Analizują adnotacje w kodzie źródłowym i mogą generować nowe pliki źródłowe, pliki zasobów lub zgłaszać błędy i ostrzeżenia kompilatora.
AbstractProcessor: klasa bazowa
Rozszerz klasę javax.annotation.processing.AbstractProcessor. Przesłoń metodę process(), aby obsługiwać oznaczone elementy. Zadeklaruj obsługiwane adnotacje i wersję źródeł Java.
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
@SupportedAnnotationTypes("com.example.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class BuilderProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element e : roundEnv.getElementsAnnotatedWith(GenerateBuilder.class)) {
generateBuilder((TypeElement) e);
}
return true;
}
private void generateBuilder(TypeElement cls) { /* generate source */ }
}Rejestrowanie procesora
Zarejestruj procesor w pliku META-INF/services/javax.annotation.processing.Processor, podając w pełni kwalifikowaną nazwę klasy. Narzędzia do budowania (Maven, Gradle) automatycznie go wykryją.
# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessorGenerowanie plików źródłowych
Użyj processingEnv.getFiler().createSourceFile(), aby zapisać nowy plik .java. Następnie kompilator skompiluje wygenerowany plik w tej samej rundzie lub w kolejnej.
JavaFileObject file = processingEnv.getFiler()
.createSourceFile("com.example.UserBuilder");
try (Writer w = file.openWriter()) {
w.write("package com.example;\n");
w.write("public class UserBuilder {\n");
w.write(" // generated builder\n");
w.write("}\n");
}Analizowanie modelu elementów
Procesory adnotacji pracują z elementami Element (nie z klasami Class — kod źródłowy nie został jeszcze skompilowany). Używaj typów TypeElement, VariableElement i ExecutableElement.
TypeElement classElement = (TypeElement) element;
String className = classElement.getSimpleName().toString();
List<VariableElement> fields = classElement.getEnclosedElements().stream()
.filter(e -> e.getKind() == ElementKind.FIELD)
.map(e -> (VariableElement) e)
.collect(Collectors.toList());Zgłaszanie błędów kompilatora
Wywołaj processingEnv.getMessager().printMessage(), aby zgłosić błędy, ostrzeżenia lub informacje. W ten sposób własne adnotacje ograniczeń sygnalizują naruszenia podczas kompilacji.
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"@GenerateBuilder requires at least one field",
element
);Przetwarzanie wielorundowe
Przetwarzanie adnotacji odbywa się w rundach. Jeśli wygenerujesz plik zawierający adnotacje, procesor może uruchomić się ponownie w następnej rundzie. roundEnv.processingOver() sygnalizuje ostatnią rundę.
if (roundEnv.processingOver()) {
// last round — write summary files or do cleanup
}Lombok od kuchni
Lombok używa niestandardowego rozszerzenia APT, które modyfikuje AST istniejących klas (co jest niedozwolone przez specyfikację). Jego adnotacje, takie jak @Data, @Builder i @Getter, generują metody bezpośrednio w skompilowanej klasie.
Generowanie kodu przez MapStruct
MapStruct generuje bezpieczne typowo implementacje mapperów podczas kompilacji. Odczytuje interfejsy oznaczone adnotacją @Mapper i zapisuje implementacje jako zwykłe klasy Java — bez refleksji w czasie wykonywania.
@Mapper
public interface UserMapper {
UserDto toDto(User user);
User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile timeTestowanie procesorów adnotacji
Użyj google/compile-testing lub Kapt (w przypadku Kotlina), aby testować procesory jednostkowo. Przekazuj ciągi źródłowe i sprawdzaj wygenerowane pliki lub błędy kompilatora.
JavaFileObject src = JavaFileObjects.forSourceString("Test",
"@GenerateBuilder public class Test { private String name; }");
Compilation c = Compiler.javac().withProcessors(new BuilderProcessor()).compile(src);
CompilationSubject.assertThat(c).succeeded();
CompilationSubject.assertThat(c).generatedSourceFile("TestBuilder");Pakowanie procesora
Umieść procesor w osobnym module Maven. Moduł adnotacji (zawierający wyłącznie adnotacje) jest zależnością compile; moduł procesora ma zakres annotationProcessor i nigdy nie jest zależnością czasu wykonywania.
// build.gradle:
dependencies {
implementation "com.example:my-annotations:1.0"
annotationProcessor "com.example:my-processor:1.0"
}Szybkie sprawdzenie
Gdzie rejestruje się procesor adnotacji, aby był automatycznie wykrywany?
Podsumowanie
Rozszerz AbstractProcessor, zarejestruj procesor w META-INF/services, generuj kod źródłowy za pomocą Filer, a błędy zgłaszaj za pomocą Messager. Pakuj procesory osobno. Używaj compile-testing do testów jednostkowych. Eliminuje to narzut refleksji w czasie wykonywania.
Często zadawane pytania
Czy lekcja „Procesory adnotacji w czasie kompilacji” jest bezpłatna?
Tak — pełny tekst „Procesory adnotacji w czasie kompilacji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Procesory adnotacji w czasie kompilacji”?
Napisz AbstractProcessor do generowania plików źródłowych lub walidowania kodu podczas kompilacji. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Procesory adnotacji w czasie kompilacji”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Definiowanie adnotacji: elementy i wartości domyślne
- Zasady retencji i typy celów
- Przetwarzanie adnotacji w czasie działania
- Procesory adnotacji w czasie kompilacji