1. Übersicht
In diesem kurzen Tutorial werden wir die @ Primary- Annotation von Spring diskutieren, die mit Version 3.0 des Frameworks eingeführt wurde.
Einfach ausgedrückt, verwenden wir @Primary , um einer Bohne eine höhere Präferenz zu geben, wenn mehrere Bohnen desselben Typs vorhanden sind.
Beschreiben wir das Problem im Detail.
2. Warum wird @Primary benötigt?
In einigen Fällen müssen wir mehr als eine Bean desselben Typs registrieren .
In diesem Beispiel haben wir JohnEmployee () - und TonyEmployee () -Beans vom Typ Employee :
@Configuration public class Config { @Bean public Employee JohnEmployee() { return new Employee("John"); } @Bean public Employee TonyEmployee() { return new Employee("Tony"); } }
Spring löst eine NoUniqueBeanDefinitionException aus, wenn wir versuchen, die Anwendung auszuführen .
Um auf Beans mit demselben Typ zuzugreifen, verwenden wir normalerweise die Annotation @Qualifier („beanName“) .
Wir wenden es am Injektionspunkt zusammen mit @Autowired an . In unserem Fall wählen wir die Beans in der Konfigurationsphase aus, sodass @Qualifier hier nicht angewendet werden kann. Weitere Informationen zur Annotation von @Qualifier erhalten Sie, indem Sie dem Link folgen.
Um dieses Problem zu beheben, bietet Spring die Annotation @Primary an .
3. Verwenden Sie @Primary With @Bean
Werfen wir einen Blick auf die Konfigurationsklasse:
@Configuration public class Config { @Bean public Employee JohnEmployee() { return new Employee("John"); } @Bean @Primary public Employee TonyEmployee() { return new Employee("Tony"); } }
Wir markieren TonyEmployee () Bean mit @Primary . Spring injiziert TonyEmployee () Bean bevorzugt gegenüber JohnEmployee () .
Lassen Sie uns nun den Anwendungskontext starten und die Employee- Bean daraus abrufen:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); Employee employee = context.getBean(Employee.class); System.out.println(employee);
Nachdem wir die Anwendung ausgeführt haben:
Employee{name='Tony'}
An der Ausgabe können wir erkennen, dass die TonyEmployee () -Instanz beim automatischen Verdrahten eine Präferenz hat .
4. Verwenden Sie @Primary With @Component
Wir können @Primary direkt für die Bohnen verwenden . Schauen wir uns das folgende Szenario an:
public interface Manager { String getManagerName(); }
Wir haben eine Manager- Oberfläche und zwei Unterklassen-Beans, DepartmentManager :
@Component public class DepartmentManager implements Manager { @Override public String getManagerName() { return "Department manager"; } }
Und die GeneralManager- Bohne:
@Component @Primary public class GeneralManager implements Manager { @Override public String getManagerName() { return "General manager"; } }
Beide überschreiben getManagerName () der Manager- Oberfläche. Beachten Sie außerdem, dass wir die GeneralManager- Bean mit @Primary markieren .
Dieses Mal ist @Primary nur dann sinnvoll, wenn wir den Komponentenscan aktivieren :
@Configuration @ComponentScan(basePackages="org.baeldung.primary") public class Config { }
Lassen Sie uns einen Dienst erstellen, der die Abhängigkeitsinjektion verwendet, während Sie die richtige Bean finden:
@Service public class ManagerService { @Autowired private Manager manager; public Manager getManager() { return manager; } }
Hier können sowohl Beans DepartmentManager als auch GeneralManager automatisch verdrahtet werden.
Da wir die GeneralManager- Bean mit @Primary markiert haben , wird sie für die Abhängigkeitsinjektion ausgewählt :
ManagerService service = context.getBean(ManagerService.class); Manager manager = service.getManager(); System.out.println(manager.getManagerName());
Die Ausgabe ist " General Manager".
5. Schlussfolgerung
In diesem Artikel haben wir etwas über die @ Primary- Annotation von Spring erfahren . Anhand der Codebeispiele haben wir die Notwendigkeit und die Anwendungsfälle von @Primary demonstriert.
Wie üblich ist der vollständige Code für diesen Artikel im GitHub-Projekt verfügbar.