Introduction aux méthodes et principes communs de Lombok

Un outil qui simplifie le code source et améliore l'efficacité de la programmation, et est utilisé pour générer du code couramment utilisé.

Deux forfaits :

  • Lombok

  • lombok.experimental (propriétés expérimentales)

comment utiliser lombok

Introduire des dépendances 

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

installer le plugin 

code utilisé dans

@Data
public class People {
    private String name;
}

Résumé des annotations courantes

@val

Lors de la déclaration d'une variable, le type de variable peut être déduit par lui-même, et il est livré avec un attribut final,

@Données

@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstrutor

@Slf4j

générer un objet de journal

@Valeur

Similaire à @Data, avec les deux différences suivantes :

  • Un constructeur avec des paramètres complets est généré ;

  • Méthodes getter uniquement, pas de méthodes setter ;

@Getter

Méthodes getter pour toutes les propriétés

@Setter

Méthodes setter pour toutes les propriétés

@Constructeur

Générer du code pour les constructeurs chaînés

@Nettoyer

Libérez ou fermez des ressources en toute sécurité, le scénario le plus courant est l'opération de fermeture de flux dans IO

@NonNull

getter : si la propriété obtenue est nulle, lance NPE

setter : si la valeur transmise est nulle lors de la définition de la propriété, lancez NPE

@ToString

Générer la méthode toString()

@SneakyThrows

Mangez l'exception levée et réduisez certains codes de capture d'essai inutiles

@NoArgsConstructor

Générer un constructeur sans argument

@AllArgsConstructor

Ajouter un constructeur avec toutes les propriétés

@EqualsAndHashCode

Générer les méthodes equals() et hashcode()

@RequiredArgsConstrutor

Un constructeur contenant des constantes et des variables marquées NotNull sera généré

l'affaire

La partie commentée est le code que lombok nous aidera à générer automatiquement.

@Slf4j

@Slf4j
public class Test {
    // private static final Logger log=LoggerFactory.getLogger(Test.class);
    public static void main(String[] args) {
        log.info("Hello world");
    }
}

@Constructeur

        Test test = Test.builder()
                .id(id)
                .page(page)
                .build();

@Data
@Builder
public class Test {

    private String id;

    private String page;
    
    /**
     @java.beans.ConstructorProperties({"id", "page"})
    Test(Long id, int page) {
        this.id = id;
        this.page = page;
    }

    public static TestBuilder builder() {
        return new TestBuilder();
    }

    public TestBuilder toBuilder() {
        return new TestBuilder().id(this.id).page(this.page);
    }

    public static class TestBuilder {
        private Long id;
        private int page;

        TestBuilder() {}

        public TestBuilder id(Long id) {
            this.id = id;
            return this;
        }

        public TestBuilder page(int page) {
            this.page = page;
            return this;
        }

        public Test build() {
            return new Test(id, page);
        }

        public String toString() {
            return "Test.TestBuilder(id=" + this.id + ", page="
                + this.page")";
        }
    */
}

@SneakyThrows

    @Test(expected = RuntimeException.class)
    @SneakyThrows
    public void test_throw_exception() {
        when(HttpClientUtil.get(anyString()).thenThrow(new RuntimeException());
        api.test("nice");
    }

@Données

@Data
public class User {

    private Long id;

    private String username;

    private String password;
    
    
    /**
    public User() {}

    public Long getId() {return this.id;}

    public String getUsername() {return this.username;}

    public String getPassword() {return this.password;}

    public void setId(Long id) {this.id = id; }

    public void setUsername(String username) {this.username = username; }

    public void setPassword(String password) {this.password = password; }

    public boolean equals(Object o) {
        if (o == this) { return true; }
        ...
        return true;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $id = this.getId();
        result = result * PRIME + ($id == null ? 43 : $id.hashCode());
        final Object $username = this.getUsername();
        ...
        return result;
    }

    protected boolean canEqual(Object other) {return other instanceof User;}

    public String toString() {
        return "User(id=" + this.getId() + ...+ ")";
    }
    */
	}
}

@Valeur

@Value
public class Test {

    (private final) Long id;

    (private final) String page;
    
    /**
    @java.beans.ConstructorProperties({"id", "page"})
    public Test(Long id, String page) {
        this.id = id;
        this.page = page;
    }

    public Long getId() {return this.id;}

    public String getPage() {return this.page;}

    public boolean equals(Object o) {
        if (o == this) { return true; }
          ...
        return true;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $id = this.getId();
        result = result * PRIME + ($id == null ? 43 : $id.hashCode());
        ...
        return result;
    }

    public String toString() {
            return "Test.TestBuilder(id=" + this.id + ", page="
                + this.page")";
        }
    */
}

Convention de code Java

  • [Recommandation] Pour les classes d'entités immuables avec trop de champs ou trop de paramètres de constructeur, il est recommandé d'utiliser lombok pour générer le constructeur

  • [Recommandation] Avant que les données de type Record ne soient prises en charge, il est recommandé que les champs de classe d'entité utilisent des annotations lombok pour générer des setters et des getters, et décident d'utiliser uniquement @Getter, @Setter ou @Data selon le principe de minimisation

  • [Recommandation] En programmation contractuelle, il est recommandé d'utiliser l'annotation non vide de l'annotation IDEA IntelliJ > Spring > Lombok pour indiquer que le paramètre n'est pas vide

avantages et inconvénients

avantage

  • Réduire efficacement la quantité de code

  • dynamique. Par exemple, lors de l'ajout ou de la soustraction de champs, il n'est pas nécessaire de se soucier de la modification de méthodes telles que Getter/Setter 

  • Améliore la lisibilité du code dans une certaine mesure

défaut

  • Introduisez des dépendances externes. Une fois que lombok est utilisé dans le package de ressources, d'autres devront installer des plugins s'ils veulent voir votre code source

  • Le code généré n'est pas intuitif et peut ne pas générer le code comme prévu

  • Intégrité réduite du code source

Problème commun

@Constructeur

Problème de valeur par défaut de la propriété. Si vous utilisez @Builder pour générer du code, la valeur par défaut de l'attribut ne sera pas valide. Vous devez utiliser @Builder.Default pour marquer l'attribut avec la valeur par défaut, par exemple :

    @Builder
    public class UserQueryParam {
        private Long id;
        private String username;
        @Builder.Default
        private int page = 1;
        @Builder.Default
        private int size = 15;
    }

@Getter

Traitement spécial des valeurs booléennes

private boolean test;

1. La règle de génération par défaut pour la méthode de lecture des attributs est is+nom d'attribut au lieu de get+nom d'attribut, c'est-à-dire isTest au lieu de getTest

2. Si le nom de l'attribut lui-même commence par is, tel que isTest, la méthode pour obtenir l'attribut est toujours isTest, pas l'embarrassant isIsTest

3. Dans les deux règles ci-dessus, il y aura une situation extrême causée par un caractère déraisonnable, c'est-à-dire qu'il y a deux attributs, l'un est nommé isTest et l'autre est test. Il s'agit essentiellement d'un problème de conception. Pour cette situation, la prise -in La méthode de traitement consiste à générer un seul isTest.Quant à l'attribut lu, cela dépend de l'ordre des attributs, et le premier est prioritaire.

@Valeur et @Données

@Value est souvent utilisé pour les classes immuables. Une classe immuable signifie qu'après la création d'une instance de la classe, les variables d'instance de l'instance ne peuvent pas être modifiées.

Semblable à @Data, il existe deux différences principales :

  • Un constructeur avec des paramètres complets est généré ;

  • Méthodes getter uniquement, pas de méthodes setter ;

@Valeur

@Données

@Getter

@Setter

@ToString

@EqualsAndHashCode

@RequiredArgsConstrutor

@AllArgsConstructor 

@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)

Les annotations identifiées par @Value ne peuvent pas être utilisées avec @RequestBody et jackson.

La raison pour laquelle la désérialisation de jackson échoue après avoir utilisé @Value et fastjson peut réussir :

 1. Jackson lit la méthode set et @Value ne génère pas la méthode set, donc elle échoue ; 

2. Fastjson lit le constructeur et @Value génère le constructeur, donc il réussit ; 

Extension : lors de l'utilisation de fastjson, utilisez @Builder pour vérifier si @NoArgsConstructor ou @AllArgsConstructor est ajouté

Principe de Lombok

Modifier l'arbre de syntaxe abstraite (AST) au moment de la compilation

@Getter(AccessLevel.PUBLIC)
public class User {

    private Long id;

    private String username;

    @Getter(AccessLevel.PRIVATE)
    private String password;
}
public class User {

    private Long id;

    private String username;

    private String password;

    public Long getId() {return this.id;}

    public String getUsername() {return this.username;

    // Field 优先级更高
    private String getPassword() {return this.password;}
}

Arbre de syntaxe AST

introduire

Lombok est traité dans le lien de l'arborescence syntaxique AST. AST est une représentation arborescente utilisée pour décrire la structure grammaticale du code du programme. Chaque nœud de l'arbre grammatical représente une structure grammaticale dans le code du programme, telle que package, type, modificateur , opérateurs , les interfaces, les valeurs de retour et même les commentaires de code peuvent tous être une structure grammaticale.

goûter

Sur Idea, vous pouvez également afficher l'arbre de syntaxe AST du code en installant le plug-in, comme indiqué dans la figure ci-dessous

Chaque attribut et chaque méthode à gauche peut trouver le nœud correspondant à droite, ainsi en manipulant les nœuds de l'arbre AST, le code peut être ajouté dynamiquement lors de la compilation.

RSC 269 

Depuis Java 6, javac a commencé à prendre en charge la spécification de l'API de traitement des annotations enfichables JSR 269. Tant que le programme implémente l'API, les annotations définies peuvent être appelées lorsque le code source Java est compilé. L'essence de Lombok est de s'appuyer sur JSR 269 pour réaliser l'utilisation du "processeur d'annotations" (outil de traitement des annotations) dans l'étape de compilation Javac pour prétraiter les annotations personnalisées et générer un "fichier de classe" qui est réellement exécuté sur la JVM.

D'après le diagramme schématique ci-dessus, on peut voir que le traitement des annotations est une étape entre l'analyse du code source Java par le compilateur et la génération du fichier de classe.

Lombok

Lombok est essentiellement un programme qui implémente la " JSR 269 API ". Dans le processus d'utilisation de javac, le processus spécifique de sa fonction est le suivant :

  1. javac analyse le code source et génère un arbre de syntaxe abstraite (AST)

  2. Appelez le programme Lombok qui implémente "JSR 269 API" pendant le fonctionnement

  3. À ce moment, Lombok traite l'AST obtenu à la première étape, trouve l'arbre de syntaxe (AST) correspondant à la classe où se trouve l'annotation @Data, puis modifie l'arbre de syntaxe (AST) pour ajouter les nœuds d'arbre correspondants définis par les méthodes getter et setter

  4. javac utilise l'arbre de syntaxe abstraite modifié (AST) pour générer des fichiers de bytecode, c'est-à-dire ajouter de nouveaux nœuds (blocs de code) à la classe

Comme le montre l'organigramme de l'exécution de Lombok ci-dessus, une fois que Javac est analysé dans un arbre de syntaxe abstraite AST, Lombok modifie dynamiquement l'AST en fonction du processeur d'annotation écrit par lui-même, en ajoutant de nouveaux nœuds (c'est-à-dire que l'annotation personnalisée Lombok a besoin pour générer du code), et enfin générer un fichier de classe de bytecode exécutable JVM par analyse.

code de base

Plusieurs annotations personnalisées à Lombok ont ​​des classes de traitement de gestionnaire correspondantes. Ce sont ces classes de gestionnaire qui remplacent, modifient et traitent réellement leurs annotations personnalisées à Lombok. Pour plus de détails sur leur mise en œuvre, veuillez vous reporter au code.

plug-in lombok

Lorsque la méthode omise à l'aide de l'annotation Lombok est appelée, une erreur indiquant que la définition est introuvable sera signalée. Dans ce cas, un traitement spécial est nécessaire. Par exemple, dans Intellij Idea, le plug-in Lombok doit être téléchargé et installé.

Je suppose que tu aimes

Origine blog.csdn.net/xue_xiaofei/article/details/126145975
conseillé
Classement