[JAVA] lombok.config lorsque vous voulez passer @Qualifier à @RequiredArgsConstructor avec lombok

Aperçu

Cette entrée explique comment faire une injection de constructeur avec @RequiredArgsConstructor sur lombok.

Motivation à l'entrée

C'est peut-être un cas peu compliqué, mais il y a peut-être d'autres personnes qui veulent le faire, alors j'espère que ce sera utile.

TL;DR;

Si vous voulez faire le titre, ajoutez la ligne suivante à lombok.config.

#lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier

La description

Code à utiliser

import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.Value;

@RequiredArgsConstructor
@ToString
@Value
public class MyComponent {
    private final String name;
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyComponentConfiguration {
    @Bean(name="myComponentA")
    public MyComponent myComponentA() {
        return new MyComponent("name A");
    }

    @Bean(name="myComponentB")
    public MyComponent myComponentB() {
        return new MyComponent("name B");
    }
}

@Service
@RequiredArgsConstructor
@Slf4j
public class MyService {
    @Qualifier("myComponentA")
    private final MyComponent myComponentAdash;
    @Qualifier("myComponentB")
    private final MyComponent myComponentBdash;

    public void sayHello() {
        log.info("myComponentA->" + myComponentAdash.getName());
        log.info("myComponentB->" + myComponentBdash.getName());
    }
}

Si vous essayez de le démarrer dans cet état, l'erreur suivante se produira.

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-07-19 22:00:45.510 ERROR 16076 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in info.beambitious.sandbox.lombokqualifiertest.MyService required a single bean, but 2 were found:
        - myComponentA: defined by method 'myComponentA' in class path resource [info/beambitious/sandbox/lombokqualifiertest/MyComponentConfiguration.class]
        - myComponentB: defined by method 'myComponentB' in class path resource [info/beambitious/sandbox/lombokqualifiertest/MyComponentConfiguration.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command 'C:\Java\Amazon Corretto\jdk1.8.0_222\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s
3 actionable tasks: 2 executed, 1 up-to-date

Dans @RequiredArgsConstructor de lombok, j'essaie de spécifier une valeur pour deux champs de type MyComponent par injection de constructeur, mais c'est une valeur différente de celle spécifiée par le nom de @ Bean et je ne peux pas le dire.

Delombok MyService et jetez un œil au code généré automatiquement.

java -jar .\lombok.jar delombok --print .\src\main\java\info\beambitious\sandbox\lombokqualifiertest\MyService.java

Le constructeur créé par @RequiredArgsConstructor de lombok n'a pas @Qualifier. ,

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @java.lang.SuppressWarnings("all")
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MyService.class);
    @Qualifier("myComponentA")
    private final MyComponent myComponentAdash;
    @Qualifier("myComponentB")
    private final MyComponent myComponentBdash;

    public void sayHello() {
        log.info("myComponentA->" + myComponentAdash.getName());
        log.info("myComponentB->" + myComponentBdash.getName());
    }

    @java.lang.SuppressWarnings("all")
    public MyService(final MyComponent myComponentAdash, final MyComponent myComponentBdash) {
        this.myComponentAdash = myComponentAdash;
        this.myComponentBdash = myComponentBdash;
    }
}

Quand je regardais StackOverflow parce que j'avais des problèmes, [est-il possible d'ajouter des qualificatifs dans @RequiredArgsConstructor (onConstructor = @__ (@Autowired))?](Https://stackoverflow.com/questions/38549657/is-it J'ai trouvé (-possible-to-add-qualifiers-in-requiredargsconstructoronconstructor).

(Référence): GitHub Issue 745 référencé dans l'article ci-dessus.

Spécifiez la valeur telle qu'introduite dans TL; DR; dans lombok.config et essayez delombok.

    @java.lang.SuppressWarnings("all")
    public MyService(@Qualifier("myComponentA") final MyComponent myComponentAdash, @Qualifier("myComponentB") final MyComponent myComponentBdash) {
        this.myComponentAdash = myComponentAdash;
        this.myComponentBdash = myComponentBdash;
    }

Cette fois, @Qualifier est écrit dans le constructeur.

Si vous le nettoyez puis l'exécutez, le programme fonctionnera normalement.

gradlew clean
gradlew bootRun

(Omission)

2020-07-19 22:18:53.006  INFO 14200 --- [           main] i.b.s.l.LombokQualifierTestApplication   : Started LombokQualifierTestApplication in 1.658 seconds (JVM running for 2.305)
2020-07-19 22:18:53.010  INFO 14200 --- [           main] i.b.s.lombokqualifiertest.MyService      : myComponentA->name A
2020-07-19 22:18:53.011  INFO 14200 --- [           main] i.b.s.lombokqualifiertest.MyService      : myComponentB->name B

en conclusion

Comme alternative, renommer les champs dans MyService fonctionnera, mais cette entrée explique comment les spécifier explicitement dans Qualifier.

    private final MyComponent myComponentA;
    private final MyComponent myComponentB;

Le code utilisé dans cette entrée se trouve sur GitHub. ](Https://github.com/hrkt/lombok-qualifier-test/releases/tag/0.0.1)

Recommended Posts

lombok.config lorsque vous voulez passer @Qualifier à @RequiredArgsConstructor avec lombok
Lorsque vous souhaitez écrire explicitement OR ou AND avec ransack
Lorsque vous souhaitez lier InputStream dans JDBI3
Lorsque vous souhaitez utiliser la méthode à l'extérieur
[Ruby] Lorsque vous souhaitez remplacer plusieurs caractères
Si vous souhaitez utiliser Mockito avec Kotlin, utilisez mockito-kotlin
Lorsque vous souhaitez remplacer dynamiquement l'annotation dans Java 8
Remarques à vérifier lorsque vous essayez d'utiliser Lombok
Code à utiliser lorsque vous souhaitez traiter Json en Java avec uniquement des bibliothèques standard
[Ruby + Rails] Lorsque vous souhaitez vous inscrire dans la liste de diffusion de Mailchimp avec l'enregistrement de l'utilisateur
Comment écrire dans la classe Model lorsque vous souhaitez enregistrer des données binaires dans DB avec PlayFramework
Delicate est pratique à utiliser lorsque vous souhaitez réutiliser des pièces
Je veux passer la commande de démarrage à postgres avec docker-compose.
ProxyFactory est pratique lorsque vous souhaitez tester AOP avec Spring!
Je veux éviter OutOfMemory lors de la sortie de gros fichiers avec POI
Lorsque vous avez introduit la devise mais que vous souhaitez ajouter plus de colonnes
[Rails] Je souhaite ajouter des données aux paramètres lors de la transition avec link_to
Pratique à utiliser lorsque vous souhaitez exécuter différents groupes de traitement en série
La première chose à faire lorsque vous voulez être satisfait d'Heroku sur GitHub avec Eclipse sur Java
Un mémo lorsque vous souhaitez effacer la partie horaire de l'agenda
Lorsque vous souhaitez que Rails désactive une session pour un contrôleur spécifique
Si vous voulez créer un fichier zip avec Ruby, c'est rubyzip.
Je souhaite utiliser DBViewer avec Eclipse 2018-12! !!
Commandes de base de Rails que vous souhaitez apprendre
Lorsque vous souhaitez notifier une erreur quelque part lors de l'utilisation de graphql-spring-boot avec Spring Boot
Code utilisé lorsque vous souhaitez traiter Json avec uniquement des bibliothèques standard en Java (version améliorée) gson inutile