Vejledning til foråret @Autowired

1. Oversigt

Fra og med foråret 2.5 introducerede rammen annoteringsdrevne Afhængighedsinjektion. Den vigtigste kommentar til denne funktion er @Autowired.Det giver Spring mulighed for at løse og injicere samarbejdende bønner i vores bønne.

I denne vejledning skal vi først se på, hvordan du aktiverer automatisk kabelføring ogforskelligemåder at autowire bønner på. Derefter taler vi om løsning af bønnekonflikter ved hjælp af @Kvalifikator kommentar, samt potentielle undtagelsesscenarier.

2. Aktivering @Autowired Kommentarer

Spring-rammen muliggør automatisk indsprøjtning af afhængighed. Med andre ord, ved at erklære alle bønneafhængigheder i en Spring-konfigurationsfil kan Spring-container autowire forholdet mellem samarbejdende bønner. Dette kaldes Forbundet autoledning.

For at bruge Java-baseret konfiguration i vores applikation, lad os aktivere annoteringsdrevet injektionfor at indlæse vores fjederkonfiguration:

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

Alternativt kan annotering bruges hovedsageligt til at aktivere annoncer for afhængighedsinjektion i Spring XML-filer.

I øvrigt, Spring Boot introducerer @SpringBootApplication kommentar. Denne enkelt anmærkning svarer til brug @Konfiguration, @EnableAutoConfigurationog @ComponentScan.

Lad os bruge denne kommentar i applikationens hovedklasse:

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

Når vi kører denne Spring Boot-applikation, den scanner automatisk komponenterne i den aktuelle pakke og dens underpakker. Det registrerer dem således i Spring's Application Context og giver os mulighed for at injicere bønner ved hjælp af @Autowired.

3. Brug @Autowired

Efter aktivering af annoteringsinjektion, vi kan bruge autoledning på egenskaber, settere og konstruktører.

3.1. @Autowired på egenskaber

Lad os se, hvordan vi kan kommentere en ejendom ved hjælp af @Autowired. Dette eliminerer behovet for getters og settere.

Lad os først definere en fooFormatter bønne:

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

Så injicerer vi denne bønne i FooService bønne ved hjælp af @Autowired om feltdefinitionen:

@Komponent offentlig klasse FooService {@Autowired privat FooFormatter fooFormatter; }

Som et resultat injicerer Spring fooFormatter hvornår FooService er oprettet.

3.2. @Autowired på Setters

Lad os nu prøve at tilføje @Autowired kommentar på en setter-metode.

I det følgende eksempel kaldes settermetoden med forekomsten af FooFormatter hvornår FooService er oprettet:

offentlig klasse FooService {privat FooFormatter fooFormatter; @Autowired public void setFooFormatter (FooFormatter fooFormatter) {this.fooFormatter = fooFormatter; }} 

3.3. @Autowired på konstruktører

Lad os endelig bruge @Autowired på en konstruktør.

Vi ser det som en forekomst af FooFormatter injiceres af Spring som et argument for FooService konstruktør:

offentlig klasse FooService {privat FooFormatter fooFormatter; @Autowired offentlig FooService (FooFormatter fooFormatter) {this.fooFormatter = fooFormatter; }}

4. @Autowired og valgfri afhængigheder

Når en bønne konstrueres, @Autowired afhængigheder skal være tilgængelige. Ellers, hvis foråret ikke kan løse en bønne til ledningsføring, kaster den en undtagelse.

Derfor forhindrer det Spring-containeren i at starte med succes med undtagelse af formularen:

Forårsaget af: org.springframework.beans.factory.NoSuchBeanDefinitionException: Ingen kvalificerende bønne af typen [com.autowire.sample.FooDAO] fundet for afhængighed: forventes mindst 1 bønne, der kvalificerer som autowire-kandidat for denne afhængighed. Afhængighedsannotationer: {@ org.springframework.beans.factory.annotation.Autowired (krævet = true)}

For at løse dette er vi nødt til at erklære en bønne af den krævede type:

offentlig klasse FooService {@Autowired (krævet = falsk) privat FooDAO dataAccessor; }

5. Autowire Disambiguation

Foråret løser som standard @Autowired poster efter type. Hvis der er mere end en bønne af samme type til rådighed i containeren, kaster rammen en fatal undtagelse.

For at løse denne konflikt er vi nødt til at fortælle Spring eksplicit, hvilken bønne vi vil injicere.

5.1. Autokabler af @Kvalifikator

Lad os for eksempel se, hvordan vi kan bruge @Kvalifikator kommentar for at angive den krævede bønne.

Først definerer vi 2 bønner af typen Formater:

@Component ("fooFormatter") offentlig klasse FooFormatter implementerer Formatter {public String format () {return "foo"; }}
@Component ("barFormatter") offentlig klasse BarFormatter implementerer Formatter {public String format () {return "bar"; }}

Lad os nu prøve at injicere en Formater bønne i FooService klasse:

offentlig klasse FooService {@Autowired privat formater formater; }

I vores eksempel er der to konkrete implementeringer af Formater tilgængelig til Spring Container. Som resultat, Foråret vil kaste en NoUniqueBeanDefinitionException undtagelse ved konstruktion af FooService:

Forårsaget af: org.springframework.beans.factory.NoUniqueBeanDefinitionException: Ingen kvalificerende bønne af typen [com.autowire.sample.Formatter] er defineret: forventet enkelt matchende bønne men fundet 2: barFormatter, fooFormatter 

Vi kan undgå dette ved at indsnævre implementeringen ved hjælp af en @Kvalifikator kommentar:

offentlig klasse FooService {@Autowired @Qualifier ("fooFormatter") privat formateringsformater; }

Når der er flere bønner af samme type, er det en god ide at brug @Kvalifikator for at undgå tvetydighed.

Vær opmærksom på, at værdien af @Kvalifikator kommentar stemmer overens med det navn, der er angivet i @Komponent kommentar af vores FooFormatter implementering.

5.2. Autotråd via brugerdefineret kvalifikator

Foråret tillader os også at Opret vores egen brugerdefinerede @Kvalifikator kommentar. For at gøre dette skal vi give @Kvalifikator kommentar med definitionen:

@Qualifier @Target ({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER}) @Retention (RetentionPolicy.RUNTIME) public @interface FormatterType {Strengværdi (); }

Så kan vi bruge FormatterType inden for forskellige implementeringer for at specificere en brugerdefineret værdi:

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

Endelig er vores brugerdefinerede kvalifikationsnotering klar til brug til autokabler:

@Komponent offentlig klasse FooService {@Autowired @FormatterType ("Foo") privat formateringsformater; } 

Den værdi, der er angivet i @Mål meta-annotation begrænser, hvor kvalifikationen skal anvendes som i vores eksempel er felter, metoder, typer og parametre.

5.3. Autokabler efter navn

Spring bruger bønnens navn som en standardkvalifikationsværdi. Det vil inspicere containeren og kigge efter en bønne med det nøjagtige navn som ejendom til autowire.

Derfor matcher foråret i vores eksempel fooFormatter ejendomsnavn til FooFormatter implementering. Derfor injicerer den den specifikke implementering under konstruktion FooService:

offentlig klasse FooService {@Autowired privat formater fooFormatter; }

6. Konklusion

I denne artikel diskuterede vi autokabler og de forskellige måder at bruge den på. Vi undersøgte også måder at løse to almindelige undtagelser fra autowiring forårsaget af enten en manglende bønne eller en tvetydig bønneinjektion.

Kildekoden til denne artikel er tilgængelig på GitHub-projektet.