0Pricing
Java Academy · Leçon

Processeurs d’annotations à la compilation

Écrivez un AbstractProcessor pour générer des fichiers source ou valider le code au moment de la compilation.

Processeurs d’annotations à la compilation est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Que sont les processeurs d'annotations

Les processeurs d'annotations (APT — Annotation Processing Tool) s'exécutent lors de la compilation. Ils inspectent les annotations du code source et peuvent générer de nouveaux fichiers source, des fichiers de ressources ou déclencher des erreurs et des avertissements du compilateur.

AbstractProcessor : la classe de base

Étendez javax.annotation.processing.AbstractProcessor. Redéfinissez process() pour traiter les éléments annotés. Déclarez les annotations prises en charge ainsi que la version du langage Java prise en charge.

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 */ }
}

Enregistrer le processeur

Enregistrez le processeur dans META-INF/services/javax.annotation.processing.Processor en indiquant le nom complet de la classe. Les outils de compilation (Maven, Gradle) le détectent automatiquement.

# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessor

Générer des fichiers source

Utilisez processingEnv.getFiler().createSourceFile() pour écrire un nouveau fichier .java. Le compilateur compile ensuite le fichier généré lors du même cycle ou du cycle suivant.

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");
}

Examiner le modèle des éléments

Les processeurs d'annotations manipulent des Element (et non des Class, car le code source n'est pas encore compilé). Utilisez TypeElement, VariableElement et 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());

Émettre des erreurs du compilateur

Appelez processingEnv.getMessager().printMessage() pour émettre des erreurs, des avertissements ou des remarques. C'est ainsi que les annotations de contrainte personnalisées signalent les violations lors de la compilation.

processingEnv.getMessager().printMessage(
    Diagnostic.Kind.ERROR,
    "@GenerateBuilder requires at least one field",
    element
);

Traitement en plusieurs cycles

Le traitement des annotations se déroule par cycles. Si vous générez un fichier contenant des annotations, le processeur peut s'exécuter de nouveau au cycle suivant. roundEnv.processingOver() signale le dernier cycle.

if (roundEnv.processingOver()) {
    // last round — write summary files or do cleanup
}

Lombok en interne

Lombok utilise une extension APT non standard qui modifie l'AST des classes existantes (ce que la spécification n'autorise pas). Ses annotations comme @Data, @Builder et @Getter génèrent directement des méthodes dans la classe compilée.

Génération de code avec MapStruct

MapStruct génère des implémentations de mappeurs sûres du point de vue des types lors de la compilation. Il lit les interfaces annotées avec @Mapper et écrit les implémentations sous forme de classes Java ordinaires, sans aucune réflexion à l'exécution.

@Mapper
public interface UserMapper {
    UserDto toDto(User user);
    User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile time

Tester les processeurs d'annotations

Utilisez google/compile-testing ou Kapt (pour Kotlin) afin de tester unitairement les processeurs. Fournissez des chaînes de code source et vérifiez les fichiers générés ou les erreurs du compilateur.

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");

Empaqueter le processeur

Empaquetez le processeur dans un module Maven séparé. Le module d'annotations (contenant uniquement les annotations) est une dépendance compile ; le module du processeur a une portée annotationProcessor et ne doit jamais être une dépendance d'exécution.

// build.gradle:
dependencies {
    implementation "com.example:my-annotations:1.0"
    annotationProcessor "com.example:my-processor:1.0"
}

Vérification rapide

Où enregistrez-vous un processeur d'annotations pour permettre sa découverte automatique ?

Récapitulatif

Étendez AbstractProcessor, enregistrez-le dans META-INF/services, générez le code source avec Filer et émettez les erreurs avec Messager. Empaquetez les processeurs séparément. Utilisez les tests de compilation pour les tests unitaires. Cela élimine le surcoût de la réflexion à l'exécution.

Questions Fréquemment Posées

La leçon « Processeurs d’annotations à la compilation » est-elle gratuite ?

Oui — le texte complet de « Processeurs d’annotations à la compilation » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Processeurs d’annotations à la compilation » ?

Écrivez un AbstractProcessor pour générer des fichiers source ou valider le code au moment de la compilation. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Processeurs d’annotations à la compilation » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Définir des annotations : éléments et valeurs par défaut
  2. Politiques de rétention et types de cibles
  3. Traitement des annotations à l’exécution
  4. Processeurs d’annotations à la compilation
← Retour à Java Academy