Cette entrée explique comment faire une injection de constructeur avec @RequiredArgsConstructor sur lombok.
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
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
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