De Spring @Qualifier-annotatie

1. Overzicht

In dit artikel zullen we onderzoeken wat de @Kwalificatie annotatie kan ons daarbij helpen, welke problemen het oplost en hoe het te gebruiken.

We zullen ook uitleggen hoe het verschilt van de @Primair annotatie en van autowiring op naam.

2. Autowire Noodzaak voor ondubbelzinnig maken

De @Autowired annotatie is een geweldige manier om de noodzaak om een ​​afhankelijkheid in Spring expliciet te maken. En hoewel het nuttig is, zijn er gebruiksscenario's waarvoor deze annotatie alleen niet voldoende is voor Spring om te begrijpen welke boon moet worden geïnjecteerd.

Standaard lost Spring automatisch bedrade items op op type.

Als er meer dan één boon van hetzelfde type in de container beschikbaar is, zal het frame gooien NoUniqueBeanDefinitionException, wat aangeeft dat er meer dan één bonen beschikbaar zijn voor automatische bedrading.

Laten we ons een situatie voorstellen waarin er twee mogelijke kandidaten zijn voor Spring om in een bepaald geval als boonmedewerker te injecteren:

@Component ("fooFormatter") public class FooFormatter implementeert Formatter {public String format () {return "foo"; }} @Component ("barFormatter") public class BarFormatter implementeert Formatter {public String format () {return "bar"; }} @Component publieke klasse FooService {@Autowired private Formatter-formatter; }

Als we proberen te laden FooService in onze context zal het Spring-raamwerk een NoUniqueBeanDefinitionException. Dit is zo omdat De lente weet niet welke boon hij moet injecteren. Om dit probleem te voorkomen, zijn er verschillende oplossingen. De @Kwalificatie annotatie is er een van.

3. @Kwalificatie Annotatie

Door de @Kwalificatie annotatie kunnen we elimineer de kwestie van welke boon moet worden geïnjecteerd.

Laten we ons vorige voorbeeld opnieuw bekijken en kijken hoe we het probleem oplossen door de @Kwalificatie annotatie om aan te geven welke boon we willen gebruiken:

openbare klasse FooService {@Autowired @Qualifier ("fooFormatter") privé Formatter-formatter; }

Door de @Kwalificatie annotatie samen met de naam van de specifieke implementatie die we willen gebruiken - in dit voorbeeld Foo - we kunnen dubbelzinnigheid vermijden wanneer Spring meerdere bonen van hetzelfde type vindt.

We moeten er rekening mee houden dat de te gebruiken kwalificatienaam de naam is die is gedeclareerd in het @Component annotatie.

Merk op dat we ook de @Kwalificatie annotatie op de Formatter klassen implementeren, in plaats van de namen in hun @Component annotaties, om hetzelfde effect te verkrijgen:

@Component @Qualifier ("fooFormatter") openbare klasse FooFormatter implementeert Formatter {// ...} @Component @Qualifier ("barFormatter") openbare klasse BarFormatter implementeert Formatter {// ...} 

4. @Kwalificatie vs @Primair

Er is nog een annotatie genaamd @Primair die we kunnen gebruiken om te beslissen welke boon we moeten injecteren als er onduidelijkheid is over afhankelijkheidsinjectie.

Deze annotatie definieert een voorkeur als er meerdere bonen van hetzelfde type aanwezig zijn. De boon in verband met de @Primair annotatie wordt gebruikt, tenzij anders aangegeven.

Laten we een voorbeeld bekijken:

@Configuratie openbare klasse Config {@Bean openbare werknemer johnEmployee () {retourneer nieuwe werknemer ("John"); } @Bean @ Primaire openbare medewerker tonyEmployee () {retourneer nieuwe medewerker ("Tony"); }}

In dit voorbeeld retourneren beide methoden hetzelfde Werknemer type. De boon die Spring zal injecteren, is degene die door de methode wordt geretourneerd tonyWerknemer. Dit komt omdat het de @Primair annotatie. Deze annotatie is handig als we dat willen specificeer welke bean van een bepaald type standaard moet worden geïnjecteerd.

En als we de andere boon op een bepaald injectiepunt nodig hebben, moeten we dit specifiek aangeven. Dat kunnen we doen via de @Kwalificatie annotatie. We kunnen bijvoorbeeld specificeren dat we de bean willen gebruiken die wordt geretourneerd door de johnWerknemer methode met behulp van de @Kwalificatie annotatie.

Het is vermeldenswaard dat als beide @Kwalificatie en @Primair annotaties aanwezig zijn, dan is het @Kwalificatie annotatie heeft voorrang. Eigenlijk, @Primair definieert een standaard, while @Kwalificatie is heel specifiek.

Laten we eens kijken naar een andere manier om het @Primair annotatie, deze keer met behulp van het eerste voorbeeld:

@Component @ Primaire openbare klasse FooFormatter implementeert Formatter {// ...} @Component openbare klasse BarFormatter implementeert Formatter {// ...} 

In dit geval is het @Primair annotatie wordt in een van de implementatieklassen geplaatst en zal het scenario ondubbelzinnig maken.

5. @Kwalificatie versus automatische bedrading op naam

Een andere manier om bij automatische bedrading te kiezen tussen meerdere bonen, is door de naam van het te injecteren veld te gebruiken. Dit is de standaardinstelling voor het geval er geen andere hints zijn voor de lente. Laten we wat code bekijken op basis van ons eerste voorbeeld:

openbare klasse FooService {@Autowired private Formatter fooFormatter; }

In dit geval zal Spring bepalen dat de te injecteren boon de FooFormatter one aangezien de veldnaam overeenkomt met de waarde die we hebben gebruikt in de @Component annotatie voor die boon.

6. Conclusie

We hebben de scenario's beschreven waarin we ondubbelzinnig moeten weten welke bonen we moeten injecteren. In het bijzonder hebben we de @Kwalificatie annotatie en vergeleken met andere vergelijkbare manieren om te bepalen welke bonen moeten worden gebruikt.

Zoals gewoonlijk is de volledige code voor dit artikel beschikbaar op GitHub.