Dieser Eintrag befasst sich mit der Konstruktorinjektion mit @RequiredArgsConstructor unter lombok.
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
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
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