Guide til våren @Autowired

1. Oversikt

Fra og med våren 2.5 introduserte rammeverket merkedrevne Avhengighetsinjeksjon. Hovedkommentarene til denne funksjonen er @Autowired.Det lar våren løse og injisere bønner som samarbeider.

I denne opplæringen tar vi først en titt på hvordan du aktiverer autokobling ogdiversemåter å autowire bønner på. Etterpå vil vi snakke om løse bønnekonflikter ved hjelp av @Kvalifikator kommentar, samt potensielle unntaksscenarier.

2. Aktivering @Autowired Kommentarer

Vårrammeverket muliggjør automatisk avhengighetsinjeksjon. Med andre ord, ved å erklære alle bønneavhengighetene i en Spring-konfigurasjonsfil, kan Spring container autowire relasjoner mellom samarbeidende bønner. Dette kalles Autobåndledning av vårbønner.

For å bruke Java-basert konfigurasjon i applikasjonen vår, la oss aktivere annotasjonsdrevet injeksjonfor å laste vår vårkonfigurasjon:

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

Alternativt kan kommentar brukes hovedsakelig for å aktivere avhengighetsinjeksjonskommentarer i XML-filer på våren.

Videre Spring Boot introduserer @SpringBootApplication kommentar. Denne enkeltkommentaren tilsvarer bruk @Konfigurasjon, @EnableAutoConfiguration, og @ComponentScan.

La oss bruke denne merknaden i hovedklassen i applikasjonen:

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

Som et resultat, når vi kjører denne Spring Boot-applikasjonen, den vil automatisk skanne komponentene i den nåværende pakken og dens underpakker. Dermed vil den registrere dem i Spring's Application Context, og tillate oss å injisere bønner ved hjelp av @Autowired.

3. Bruke @Autowired

Etter at du har aktivert annoteringsinjeksjon, vi kan bruke autoledning på eiendommer, settere og konstruktører.

3.1. @Autowired på eiendommer

La oss se hvordan vi kan kommentere en eiendom ved hjelp av @Autowired. Dette eliminerer behovet for getters og settere.

La oss først definere en fooFormatter bønne:

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

Så injiserer vi denne bønnen i FooService bønne ved hjelp av @Autowired på feltdefinisjonen:

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

Som et resultat injiserer Spring fooFormatter når FooService er skapt.

3.2. @Autowired på Setters

La oss nå prøve å legge til @Autowired kommentar på en settermetode.

I det følgende eksemplet kalles settermetoden med forekomsten av FooFormatter når FooService er skapt:

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

3.3. @Autowired på konstruktører

Til slutt, la oss bruke @Autowired på en konstruktør.

Vi får se en forekomst av FooFormatter blir injisert av Spring som et argument for FooService konstruktør:

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

4. @Autowired og valgfrie avhengigheter

Når en bønne blir konstruert, vil @Autowired avhengigheter bør være tilgjengelige. Ellers, Hvis våren ikke kan løse en bønne for ledninger, vil den kaste et unntak.

Derfor forhindrer det at Spring Container kan starte vellykket med unntak av skjemaet:

Forårsaket av: org.springframework.beans.factory.NoSuchBeanDefinitionException: Ingen kvalifiserende bønner av typen [com.autowire.sample.FooDAO] funnet for avhengighet: forventet minst 1 bønne som kvalifiserer som autowire-kandidat for denne avhengigheten. Avhengighetsanmerkninger: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}

For å fikse dette må vi erklære en bønne av ønsket type:

offentlig klasse FooService {@Autowired (obligatorisk = falsk) privat FooDAO dataAccessor; }

5. Autowire Disambiguation

Som standard løser våren seg @Autowired oppføringer etter type. Hvis mer enn en bønne av samme type er tilgjengelig i containeren, vil rammeverket kaste et dødelig unntak.

For å løse denne konflikten, må vi fortelle Spring eksplisitt hvilken bønne vi vil injisere.

5.1. Autokabler av @Kvalifiserende

La oss for eksempel se hvordan vi kan bruke @Kvalifiserende kommentar for å indikere ønsket bønne.

Først definerer vi to bønner av typen Formaterer:

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

La oss nå prøve å injisere en Formaterer bønne i FooService klasse:

offentlig klasse FooService {@Autowired private Formatter formatter; }

I vårt eksempel er det to konkrete implementeringer av Formaterer tilgjengelig for vårcontaineren. Som et resultat, Våren vil kaste en NoUniqueBeanDefinitionException unntak ved konstruksjon av FooService:

Forårsaket av: org.springframework.beans.factory.NoUniqueBeanDefinitionException: Ingen kvalifiserende bønner av typen [com.autowire.sample.Formatter] er definert: forventet enkelt matchende bønne men funnet 2: barFormatter, fooFormatter 

Vi kan unngå dette ved å begrense implementeringen ved hjelp av en @Kvalifiserende kommentar:

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

Når det er flere bønner av samme type, er det lurt å gjøre det bruk @Kvalifikator for å unngå tvetydighet.

Vær oppmerksom på at verdien av @Kvalifikator merknader samsvarer med navnet deklarert i @Komponent kommentar av vår FooFormatter gjennomføring.

5.2. Autokabler etter egendefinert kvalifisering

Våren lar oss også lage vår egen skikk @Kvalifiserende kommentar. For å gjøre det, bør vi tilby @Kvalifiserende kommentar med definisjonen:

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

Da kan vi bruke FormatterType innenfor forskjellige implementeringer for å spesifisere en tilpasset verdi:

@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 vår tilpassede kvalifiseringsmerknad klar til bruk for autokobling:

@Komponent offentlig klasse FooService {@Autowired @FormatterType ("Foo") privat formateringsformatør; } 

Verdien spesifisert i @Mål meta-kommentar begrenser hvor kvalifiseringen skal brukes, som i vårt eksempel er felt, metoder, typer og parametere.

5.3. Autokabler etter navn

Spring bruker bønnens navn som en standard kvalifiseringsverdi. Den vil inspisere beholderen og se etter en bønne med det eksakte navnet som eiendommen for å autoledre den.

Derfor, i vårt eksempel, samsvarer våren med fooFormatter eiendomsnavn til FooFormatter gjennomføring. Derfor injiserer den den spesifikke implementeringen når du konstruerer FooService:

offentlig klasse FooService {@Autowired private Formatter fooFormatter; }

6. Konklusjon

I denne artikkelen diskuterte vi autowiring og de forskjellige måtene å bruke den på. Vi undersøkte også måter å løse to vanlige unntak for autoledning forårsaket av enten en manglende bønne eller en tvetydig bønneinjeksjon.

Kildekoden til denne artikkelen er tilgjengelig på GitHub-prosjektet.