[JAVA] lombok.config, wenn Sie @Qualifier mit lombok an @RequiredArgsConstructor übergeben möchten

Überblick

Dieser Eintrag befasst sich mit der Konstruktorinjektion mit @RequiredArgsConstructor unter lombok.

Motivation für den Einstieg

Es mag ein kleiner Randfall sein, aber es mag andere Leute geben, die es tun wollen, also hoffe ich, dass es hilfreich sein wird.

TL;DR;

Wenn Sie etwas gegen den Titel unternehmen möchten, fügen Sie die folgende Zeile zu lombok.config hinzu.

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

Erläuterung

Zu verwendender Code

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

Wenn Sie versuchen, es in diesem Zustand zu starten, tritt der folgende Fehler auf.

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

In @RequiredArgsConstructor von lombok versuche ich, einen Wert für zwei Felder vom Typ MyComponent durch Konstruktorinjektion anzugeben, aber es ist ein anderer Wert als der, der durch den Namen von @ Bean angegeben wird, und ich kann es nicht sagen.

Delombok MyService und sehen Sie sich den automatisch generierten Code an.

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

Der von @RequiredArgsConstructor von lombok erstellte Konstruktor verfügt nicht über @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;
    }
}

Wenn ich mir StackOverflow angesehen habe, weil ich in Schwierigkeiten war, [ist es möglich, Qualifikationsmerkmale in @RequiredArgsConstructor (onConstructor = @__ (@Autowired)) hinzuzufügen?](Https://stackoverflow.com/questions/38549657/is-it Ich habe gefunden (-pos -ible-to-add-qualifiers-in-requiredargsconstructoronconstructor).

(Referenz): GitHub Issue 745, auf den im obigen Artikel verwiesen wird.

Geben Sie den in TL; DR; in lombok.config eingeführten Wert an und versuchen Sie es mit delombok.

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

Dieses Mal wird @Qualifier in den Konstruktor geschrieben.

Wenn Sie es bereinigen und dann ausführen, funktioniert das Programm normal.

gradlew clean
gradlew bootRun

(Unterlassung)

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

abschließend

Alternativ können Sie die Felder in MyService umbenennen, und es funktioniert. In diesem Eintrag wird jedoch beschrieben, wie Sie sie in Qualifier explizit angeben.

    private final MyComponent myComponentA;
    private final MyComponent myComponentB;

Der in diesem Eintrag verwendete Code ist auf GitHub zu finden. ](Https://github.com/hrkt/lombok-qualifier-test/releases/tag/0.0.1)

Recommended Posts

lombok.config, wenn Sie @Qualifier mit lombok an @RequiredArgsConstructor übergeben möchten
Wenn Sie explizit ODER oder UND mit Ransack schreiben möchten
Wenn Sie InputStream in JDBI3 binden möchten
Wenn Sie die Methode außerhalb verwenden möchten
[Ruby] Wenn Sie mehrere Zeichen ersetzen möchten
Wenn Sie Mockito mit Kotlin verwenden möchten, verwenden Sie Mockito-Kotlin
Wenn Sie Annotation in Java 8 dynamisch ersetzen möchten
Hinweise zur Überprüfung bei der Verwendung von Lombok
Code, der verwendet werden soll, wenn Sie Json nur mit Standardbibliotheken in Java verarbeiten möchten
[Ruby + Rails] Wenn Sie sich zusammen mit der Benutzerregistrierung in der Mailchimp-Mailingliste registrieren möchten
So schreiben Sie in die Modellklasse, wenn Sie mit PlayFramework Binärdaten in der Datenbank speichern möchten
Delicate ist praktisch, wenn Sie Teile wiederverwenden möchten
Ich möchte den Startbefehl mit Docker-Compose an Postgres übergeben.
ProxyFactory ist praktisch, wenn Sie AOP mit Spring testen möchten!
Ich möchte OutOfMemory bei der Ausgabe großer Dateien mit POI vermeiden
Wenn Sie devise eingeführt haben, aber weitere Spalten hinzufügen möchten
[Rails] Ich möchte beim Übergang mit link_to Daten zu Params hinzufügen
Üben Sie die Verwendung, wenn Sie verschiedene Verarbeitungsgruppen seriell ausführen möchten
Das erste, was Sie tun müssen, wenn Sie mit Heroku auf GitHub mit Eclipse auf Java zufrieden sein möchten
Ein Memo, wenn Sie den Zeitteil des Kalenders löschen möchten
Wenn Rails eine Sitzung für einen bestimmten Controller deaktivieren soll
Wenn Sie mit Ruby eine Zip-Datei erstellen möchten, ist dies Rubyzip.
Ich möchte DBViewer mit Eclipse 2018-12 verwenden! !!
Grundlegende Rails-Befehle, die Sie lernen möchten
Wenn Sie irgendwo einen Fehler melden möchten, wenn Sie graphql-spring-boot mit Spring Boot verwenden
Code, der verwendet wird, wenn Sie Json nur mit Standardbibliotheken in Java (verbesserte Version) verarbeiten möchten. Gson ist nicht erforderlich