Forstå getBean () om våren

1. Introduksjon

I denne opplæringen skal vi gå gjennom forskjellige varianter av BeanFactory.getBean () metode.

Enkelt sagt, som navnet på metoden også antyder, detteer ansvarlig for å hente en bønneinstans fra Spring container.

2. Oppsett av vårbønner

La oss først definere noen få vårbønner for testing. Det er flere måter vi kan gi bønnedefinisjoner for Spring container, men i vårt eksempel bruker vi kommentarbasert Java-konfigurasjon:

@Configuration class AnnotationConfig {@Bean (name = {"tiger", "kitty"}) @Scope (value = "prototype") Tiger getTiger (String name) {return new Tiger (name); } @Bean (name = "lion") Lion getLion () {return new Lion ("Hardcoded lion name"); } grensesnitt Animal {}} 

Vi har laget to bønner. Løve har standard singleton-omfang. Tiger er eksplisitt satt til prototypes omfang. I tillegg, vær oppmerksom på at vi definerte navn for hver bønne som vi vil bruke i ytterligere forespørsler.

3. Den getBean () APIer

BeanFactory gir fem forskjellige signaturer av getBean () metoden som vi skal undersøke i de følgende underavsnittene.

3.1. Henter Bean etter navn

La oss se hvordan vi kan hente en Løve bønneinstans ved å bruke navnet:

Objekt løve = context.getBean ("løve"); assertEquals (Lion.class, lion.getClass ());

I denne varianten gir vi et navn, og til gjengjeld får vi en forekomst av Gjenstand klasse hvis en bønne med gitt navn eksisterer i applikasjonssammenheng. Ellers kaster både dette og alle andre implementeringer NoSuchBeanDefinitionException hvis bønnesøk mislykkes.

Den største ulempen er at etter å ha hentet bønnen, må vi kaste den til ønsket type. Dette kan gi et annet unntak hvis den returnerte bønnen har en annen type enn vi forventet.

Anta at vi prøver å få en Tiger bruker navnet "løve". Når vi kaster resultatet til Tiger, det vil kaste a ClassCastException:

assertThrows (ClassCastException.class, () -> {Tiger tiger = (Tiger) context.getBean ("lion");});

3.2. Henter Bean etter navn og type

Her må vi spesifisere både navnet og typen på den forespurte bønnen:

Lion lion = context.getBean ("løve", Lion.class);

Sammenlignet med den forrige metoden er denne tryggere fordi vi får informasjon om typefeil samsvar umiddelbart:

assertThrows (BeanNotOfRequiredTypeException.class, () -> context.getBean ("løve", Tiger.class)); }

3.3. Henter bønne etter type

Med den tredje varianten av getBean (), det er nok å bare spesifisere bønnetypen:

Lion løve = context.getBean (Lion.class);

I dette tilfellet må vi være spesielt oppmerksom på et potensielt tvetydig utfall:

assertThrows (NoUniqueBeanDefinitionException.class, () -> context.getBean (Animal.class)); }

I eksemplet ovenfor, fordi begge Løve og Tiger implementere Dyr bare å spesifisere type er ikke nok til å entydig bestemme resultatet. Derfor får vi en NoUniqueBeanDefinitionException.

3.4. Henter bønne etter navn med konstruktorparametere

I tillegg til bønnenavnet kan vi også overføre konstruktorparametere:

Tiger tiger = (Tiger) context.getBean ("tiger", "Siberian");

Denne metoden er litt annerledes fordi den bare gjelder bønner med prototype.

Når det gjelder singler, skal vi få en BeanDefinitionStoreException.

Fordi en prototype bønne vil returnere en nylig opprettet forekomst hver gang den blir bedt om det fra applikasjonsbeholderen, vi kan tilby konstruktørparametere på farten når man påkaller getBean ():

Tiger tiger = (Tiger) context.getBean ("tiger", "Siberian"); Tiger secondTiger = (Tiger) context.getBean ("tiger", "Striped"); assertEquals ("Siberian", tiger.getName ()); assertEquals ("Striped", secondTiger.getName ());

Som vi kan se, hver Tiger får et annet navn i henhold til det vi spesifiserte som en andre parameter når vi ba om bønnen.

3.5. Henter bønne etter type med konstruktorparametere

Denne metoden er analog med den siste, men vi må sende typen i stedet for navnet som det første argumentet:

Tiger tiger = context.getBean (Tiger.class, "Shere Khan"); assertEquals ("Shere Khan", tiger.getName ());

I likhet med å hente en bønne etter navn med konstruktorparametere, denne metoden gjelder bare bønner med prototypes omfang.

4. Hensyn til bruken

Til tross for å være definert i BeanFactory grensesnitt, getBean () metoden er oftest tilgjengelig via ApplicationContext. Typisk, vi ønsker ikke å bruke getBean () metode direkte i vårt program.

Bønner skal håndteres av beholderen. Hvis vi vil bruke en av dem, bør vi stole på avhengighetsinjeksjon i stedet for en direkte oppfordring til ApplicationContext.getBean (). På den måten kan vi unngå å blande applikasjonslogikk med rammerelaterte detaljer.

5. Konklusjon

I denne raske opplæringen gikk vi gjennom alle implementeringer av getBean () metoden fra BeanFactory grensesnitt og beskrevet fordeler og ulemper med hver.

Alle kodeeksemplene som vises her, er tilgjengelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found