Hurtigguide til vårbønneomfang

1. Oversikt

I denne raske opplæringen lærer du om de forskjellige typer bønneomfang i vårrammen.

Omfanget av en bønne definerer livssyklusen og synligheten til den bønnen i de sammenhengene den brukes i.

Den siste versjonen av Spring framework definerer 6 typer omfang:

  • singleton
  • prototype
  • be om
  • økt
  • applikasjon
  • nettstikkontakt

De fire siste omtalene forespørsel, økt, søknad og nettstikkontakt er bare tilgjengelig i et nettbevisst program.

2. Singleton Scope

Definere en bønne med singleton omfang betyr at beholderen oppretter en enkelt forekomst av den bønnen, og alle forespørsler om det bønnenavnet vil returnere det samme objektet som er hurtigbufret. Eventuelle modifikasjoner av objektet vil gjenspeiles i alle referanser til bønnen. Dette omfanget er standardverdien hvis det ikke er spesifisert noe annet omfang.

La oss lage en Person enhet for å eksemplifisere begrepet omfang:

offentlig klasse Person {private Strengnavn; // standard konstruktør, getters og setters}

Etterpå definerer vi bønnen med singleton omfang ved å bruke @Omfang kommentar:

@Bean @Scope ("singleton") offentlig person personSingleton () {returner ny person (); }

Vi kan også bruke en konstant i stedet for String verdi på følgende måte:

@Scope (verdi = ConfigurableBeanFactory.SCOPE_SINGLETON)

Nå fortsetter vi med å skrive en test som viser at to objekter som refererer til samme bønne, vil ha de samme verdiene, selv om bare en av dem endrer tilstand, da de begge refererer til samme bønneinstans:

privat statisk finale String NAME = "John Smith"; @Test offentlig ugyldighet gittSingletonScope_whenSetName_thenEqualNames () {ApplicationContext applicationContext = ny ClassPathXmlApplicationContext ("scopes.xml"); Person personSingletonA = (Person) applicationContext.getBean ("personSingleton"); Person personSingletonB = (Person) applicationContext.getBean ("personSingleton"); personSingletonA.setName (NAME); Assert.assertEquals (NAME, personSingletonB.getName ()); ((AbstractApplicationContext) applicationContext) .close (); }

De scopes.xml filen i dette eksemplet skal inneholde xml-definisjonene av bønnene som brukes:

3. Prototype Omfang

En bønne med prototype scope returnerer en annen forekomst hver gang det blir bedt om det fra containeren. Det defineres ved å sette verdien prototype til @Omfang kommentar i bønnedefinisjonen:

@Bean @Scope ("prototype") offentlig person personPrototype () {returner ny person (); }

Vi kunne også bruke en konstant som vi gjorde for singleton-omfanget:

@Scope (verdi = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Vi vil nå skrive en lignende test som før som viser at to objekter som ber om det samme bønnenavnet med prototype, vil ha forskjellige tilstander, ettersom de ikke lenger refererer til samme bønneinstans:

privat statisk finale String NAME = "John Smith"; privat statisk finale String NAME_OTHER = "Anna Jones"; @Test offentlig ugyldig givenPrototypeScope_whenSetNames_thenDifferentNames () {ApplicationContext applicationContext = new ClassPathXmlApplicationContext ("scopes.xml"); Person personPrototypeA = (Person) applicationContext.getBean ("personPrototype"); Person personPrototypeB = (Person) applicationContext.getBean ("personPrototype"); personPrototypeA.setName (NAME); personPrototypeB.setName (NAME_OTHER); Assert.assertEquals (NAME, personPrototypeA.getName ()); Assert.assertEquals (NAME_OTHER, personPrototypeB.getName ()); ((AbstractApplicationContext) applicationContext) .close (); } 

De scopes.xml filen ligner den som ble presentert i forrige avsnitt mens du la til xml-definisjonen for bønnen med prototype omfang:

4. Web-bevisste omfang

Som nevnt er det fire ekstra omfang som bare er tilgjengelige i en nettbevisst applikasjonssammenheng. Disse brukes sjeldnere i praksis.

De be om scope oppretter en bønneinstans for en enkelt HTTP-forespørsel mens session omfang oppretter for en HTTP-økt.

De applikasjon omfang oppretter bønneinstansen for livssyklusen til en ServletContext og nettstikkontakt omfang skaper det for et bestemt WebSocket økt.

La oss lage en klasse som skal brukes til å instantiere bønnene:

offentlig klasse HelloMessageGenerator {privat strengmelding; // standard getter og setter}

4.1. Be om omfang

Vi kan definere bønnen med be om omfang ved hjelp av @Omfang kommentar:

@Bean @Scope (verdi = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) offentlig HelloMessageGenerator requestScopedBean () {returner nye HelloMessageGenerator (); }

De proxyMode attributt er nødvendig fordi det i øyeblikket for øyeblikkeliggjøring av nettapplikasjonskonteksten ikke er noen aktiv forespørsel. Våren vil opprette en fullmektig som skal injiseres som en avhengighet, og instantiere målbønnen når det er nødvendig i en forespørsel.

Vi kan også bruke en @RequestScope sammensatt kommentar som fungerer som en snarvei for definisjonen ovenfor:

@Bean @RequestScope offentlig HelloMessageGenerator requestScopedBean () {returner ny HelloMessageGenerator (); }

Deretter kan vi definere en kontroller som har en injisert referanse til requestScopedBean. Vi trenger tilgang til den samme forespørselen to ganger for å teste de nettspesifikke omfangene.

Hvis vi viser beskjed hver gang forespørselen kjøres, kan vi se at verdien tilbakestilles til null, selv om det senere er endret i metoden. Dette skyldes at en annen bønneinstans returneres for hver forespørsel.

@Controller offentlig klasse ScopesController {@Resource (name = "requestScopedBean") HelloMessageGenerator requestScopedBean; @RequestMapping ("/ scopes / request") offentlig String getRequestScopeMessage (endelig modellmodell) {model.addAttribute ("previousMessage", requestScopedBean.getMessage ()); requestScopedBean.setMessage ("God morgen!"); model.addAttribute ("currentMessage", requestScopedBean.getMessage ()); returner "scopesExample"; }}

4.2. Øktens omfang

Vi kan definere bønnen med økt omfang på en lignende måte:

@Bean @Scope (verdi = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) offentlig HelloMessageGenerator sessionScopedBean () {returner nye HelloMessageGenerator (); }

Det er også en dedikert komponert kommentar vi kan bruke for å forenkle bønnedefinisjonen:

@Bean @SessionScope offentlig HelloMessageGenerator sessionScopedBean () {returner nye HelloMessageGenerator (); }

Deretter definerer vi en kontroller med en referanse til sessionScopedBean. Igjen, vi må kjøre to forespørsler for å vise at verdien av beskjed feltet er det samme for økten.

I dette tilfellet, når forespørselen kommer for første gang, verdien beskjed er null. Men når den først er endret, beholdes denne verdien for etterfølgende forespørsler, siden samme forekomst av bønnen returneres for hele økten.

@Controller offentlig klasse ScopesController {@Resource (name = "sessionScopedBean") HelloMessageGenerator sessionScopedBean; @RequestMapping ("/ scopes / session") offentlig String getSessionScopeMessage (endelig modellmodell) {model.addAttribute ("previousMessage", sessionScopedBean.getMessage ()); sessionScopedBean.setMessage ("God ettermiddag!"); model.addAttribute ("currentMessage", sessionScopedBean.getMessage ()); returner "scopesExample"; }}

4.3. Søknadsomfang

De applikasjon omfang oppretter bønneinstansen for livssyklusen til en ServletContext.

Dette ligner på singleton-omfanget, men det er en veldig viktig forskjell med hensyn til bønnens omfang.

Når bønner er applikasjon scoped samme forekomst av bønnen deles over flere servletbaserte applikasjoner som kjører i det samme ServletContext, mens singleton-scoped bønner er scoped til en enkelt applikasjonskontekst.

La oss lage bønnen med applikasjon omfang:

@Bean @Scope (verdi = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS) offentlig HelloMessageGenerator applicationScopedBean () {returner nye HelloMessageGenerator (); }

Analogt som for be om og økt omfang, kan vi bruke en kortere versjon:

@Bean @ApplicationScope offentlig HelloMessageGenerator applicationScopedBean () {returner nye HelloMessageGenerator (); }

La oss nå lage en kontroller som refererer til denne bønnen:

@Controller offentlig klasse ScopesController {@Resource (name = "applicationScopedBean") HelloMessageGenerator applicationScopedBean; @RequestMapping ("/ scopes / application") offentlig streng getApplicationScopeMessage (endelig modellmodell) {model.addAttribute ("previousMessage", applicationScopedBean.getMessage ()); applicationScopedBean.setMessage ("God ettermiddag!"); model.addAttribute ("currentMessage", applicationScopedBean.getMessage ()); returner "scopesExample"; }}

I dette tilfellet verdi beskjed en gang satt i applicationScopedBean vil bli beholdt for alle påfølgende forespørsler, økter og til og med for en annen servletapplikasjon som får tilgang til denne bønnen, forutsatt at den kjører i samme ServletContext.

4.4. WebSocket-omfang

Til slutt, la oss lage bønnen med nettstikkontakt omfang:

@Bean @Scope (scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS) offentlig HelloMessageGenerator websocketScopedBean () {returner nye HelloMessageGenerator (); }

WebSocket-scoped bønner når du først har tilgang til dem lagres i WebSocket øktattributter. Den samme forekomsten av bønnen returneres deretter når den blir brukt i løpet av hele WebSocket økt.

Vi kan også si at den viser singleton-oppførsel, men begrenset til a WebSocket bare økten.

5. Konklusjon

Vi har demonstrert forskjellige bønneomfang levert av Spring og hva de er beregnet på.

Implementeringen av denne veiledningen finner du i GitHub-prosjektet - dette er et formørkelsesbasert prosjekt, så det skal være enkelt å importere og kjøre som det er.


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