Gids voor Spring @Autowired

1. Overzicht

Vanaf Spring 2.5 introduceerde het framework annotatiegestuurd Afhankelijkheidsinjectie. De belangrijkste annotatie van deze functie is @Autowired.Het stelt Spring in staat om samenwerkende bonen op te lossen en in onze boon te injecteren.

In deze zelfstudie bekijken we eerst hoe u autowiring en deverschillendemanieren om bonen automatisch te bedraden. Daarna zullen we erover praten bonenconflicten oplossen met @Kwalificatie annotatie, evenals mogelijke uitzonderingsscenario's.

2. Inschakelen @Autowired Annotaties

Het Spring-framework maakt automatische afhankelijkheidsinjectie mogelijk. Met andere woorden, door alle bean-afhankelijkheden in een Spring-configuratiebestand te declareren, kan Spring-container relaties tussen samenwerkende bonen automatisch bedraden. Dit heet Automatische bedrading van lentebonen.

Laten we, om op Java gebaseerde configuratie in onze applicatie te gebruiken, annotatiegestuurde injectie inschakelenom onze Spring-configuratie te laden:

@Configuration @ComponentScan ("com.baeldung.autowire.sample") openbare klasse AppConfig {}

Als alternatief kan de annotatie wordt voornamelijk gebruikt om de afhankelijkheidsinjectie-annotaties in Spring XML-bestanden te activeren.

Bovendien, Spring Boot introduceert de @SpringBootApplication annotatie. Deze enkele annotatie komt overeen met het gebruik van @Configuratie, @EnableAutoConfiguration, en @BuienRadarNL.

Laten we deze annotatie gebruiken in de hoofdklasse van de applicatie:

@SpringBootApplication klasse VehicleFactoryApplication {public static void main (String [] args) {SpringApplication.run (VehicleFactoryApplication.class, args); }}

Als gevolg hiervan, wanneer we deze Spring Boot-applicatie uitvoeren, het scant automatisch de componenten in het huidige pakket en zijn subpakketten. Het registreert ze dus in de toepassingscontext van Spring en stelt ons in staat bonen te injecteren met @Autowired.

3. Met behulp van @Autowired

Na het inschakelen van annotatie-injectie, we kunnen automatische bedrading gebruiken op eigenschappen, setters en constructeurs.

3.1. @Autowired op Eigenschappen

Laten we eens kijken hoe we een eigenschap kunnen annoteren met @Autowired. Dit elimineert de behoefte aan getters en setters.

Laten we eerst een fooFormatter Boon:

@Component ("fooFormatter") public class FooFormatter {public String format () {return "foo"; }}

Dan injecteren we deze boon in de FooService boon gebruiken @Autowired op de velddefinitie:

@Component openbare klasse FooService {@Autowired privé FooFormatter fooFormatter; }

Als resultaat injecteert Spring fooFormatter wanneer FooService is gecreëerd.

3.2. @Autowired op Setters

Laten we nu proberen toe te voegen @Autowired annotatie op een setter-methode.

In het volgende voorbeeld wordt de setter-methode aangeroepen met de instantie van FooFormatter wanneer FooService is gecreëerd:

openbare klasse FooService {privé FooFormatter fooFormatter; @Autowired openbare leegte setFooFormatter (FooFormatter fooFormatter) {this.fooFormatter = fooFormatter; }} 

3.3. @Autowired op Constructors

Laten we tot slot gebruiken @Autowired op een constructor.

We zullen zien dat een instantie van FooFormatter wordt door Spring geïnjecteerd als argument voor de FooService constructeur:

openbare klasse FooService {privé FooFormatter fooFormatter; @Autowired openbare FooService (FooFormatter fooFormatter) {this.fooFormatter = fooFormatter; }}

4. @Autowired en optionele afhankelijkheden

Wanneer een boon wordt gemaakt, wordt de @Autowired afhankelijkheden moeten beschikbaar zijn. Anders, als Spring een boon voor bedrading niet kan oplossen, genereert het een uitzondering.

Bijgevolg verhindert het dat de Spring-container met succes wordt gelanceerd, met uitzondering van de vorm:

Veroorzaakt door: org.springframework.beans.factory.NoSuchBeanDefinitionException: Geen kwalificerende bean van het type [com.autowire.sample.FooDAO] gevonden voor afhankelijkheid: verwacht ten minste 1 bean die kwalificeert als autowire-kandidaat voor deze afhankelijkheid. Afhankelijkheidsaantekeningen: {@ org.springframework.beans.factory.annotation.Autowired (vereist = waar)}

Om dit op te lossen, moeten we een boon van het vereiste type declareren:

openbare klasse FooService {@Autowired (verplicht = false) privé FooDAO dataAccessor; }

5. Autowire ondubbelzinnig

Spring lost standaard op @Autowired vermeldingen op type. Als er meer dan één bean van hetzelfde type in de container beschikbaar is, genereert het framework een fatale uitzondering.

Om dit conflict op te lossen, moeten we Spring expliciet vertellen welke boon we willen injecteren.

5.1. Automatische bedrading door @Kwalificatie

Laten we bijvoorbeeld eens kijken hoe we de @Kwalificatie annotatie om de vereiste boon aan te geven.

Eerst zullen we 2 soorten bonen definiëren Formatter:

@Component ("fooFormatter") public class FooFormatter implementeert Formatter {public String format () {return "foo"; }}
@Component ("barFormatter") public class BarFormatter implementeert Formatter {public String format () {return "bar"; }}

Laten we nu proberen een Formatter boon in de FooService klasse:

openbare klasse FooService {@Autowired private Formatter-formatter; }

In ons voorbeeld zijn er twee concrete implementaties van Formatter beschikbaar voor de Spring container. Als resultaat, De lente zal een NoUniqueBeanDefinitionException uitzondering bij het construeren van de FooService:

Veroorzaakt door: org.springframework.beans.factory.NoUniqueBeanDefinitionException: er is geen kwalificerende bean van het type [com.autowire.sample.Formatter] gedefinieerd: verwachte enkele overeenkomende bean maar gevonden 2: barFormatter, fooFormatter 

We kunnen dit voorkomen door de implementatie te verkleinen met een @Kwalificatie annotatie:

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

Als er meerdere bonen van dezelfde soort zijn, is het een goed idee om dat te doen gebruik @Kwalificatie om dubbelzinnigheid te voorkomen.

Houd er rekening mee dat de waarde van de @Kwalificatie annotatie komt overeen met de naam die is gedeclareerd in de @Component annotatie van onze FooFormatter implementatie.

5.2. Autowiring door Custom Qualifier

De lente stelt ons ook in staat creëer onze eigen gewoonte @Kwalificatie annotatie. Om dit te doen, moeten we de @Kwalificatie annotatie met de definitie:

@Qualifier @Target ({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER}) @Retention (RetentionPolicy.RUNTIME) openbaar @interface FormatterType {Stringwaarde (); }

Dan kunnen we de FormatterType binnen verschillende implementaties om een ‚Äč‚Äčaangepaste waarde op te geven:

@FormatterType ("Foo") @Component public class FooFormatter implementeert Formatter {public String format () {return "foo"; }}
@FormatterType ("Bar") @Component public class BarFormatter implementeert Formatter {public String format () {return "bar"; }}

Eindelijk is onze aangepaste kwalificatie-annotatie klaar voor gebruik voor automatische bedrading:

@Component openbare klasse FooService {@Autowired @FormatterType ("Foo") privé Formatter-formatter; } 

De waarde die is opgegeven in het @Doelwit meta-annotatie beperkt waar de kwalificatie moet worden toegepast, wat in ons voorbeeld velden, methoden, typen en parameters zijn.

5.3. Automatische bedrading op naam

Spring gebruikt de naam van de bonen als een standaardkwalificatiewaarde. Het zal de container inspecteren en zoeken naar een boon met de exacte naam als de eigenschap om deze automatisch te bedraden.

Daarom komt Spring in ons voorbeeld overeen met de fooFormatter eigenschapnaam naar de FooFormatter implementatie. Daarom injecteert het die specifieke implementatie bij het construeren FooService:

openbare klasse FooService {@Autowired private Formatter fooFormatter; }

6. Conclusie

In dit artikel hebben we de automatische bedrading besproken en de verschillende manieren om deze te gebruiken. We onderzochten ook manieren om twee veelvoorkomende uitzonderingen voor automatische bedrading op te lossen die worden veroorzaakt door een ontbrekende boon of een onduidelijke booninjectie.

De broncode van dit artikel is beschikbaar op het GitHub-project.