Stručný sprievodca rozsahom jarných bôbov

1. Prehľad

V tomto rýchlom výučbe sa dozviete o rôznych druhoch rozsahu fazule v jarnom rámci.

Rozsah fazule definuje životný cyklus a viditeľnosť tejto fazule v kontextoch, v ktorých sa používa.

Posledná verzia rámca Spring definuje 6 typov rozsahov:

  • singleton
  • prototyp
  • žiadosť
  • zasadanie
  • žiadosť
  • websocket

Posledné štyri spomenuté oblasti žiadosť, relácia, žiadosť a websocket sú k dispozícii iba v aplikácii využívajúcej web.

2. Rozsah platnosti Singleton

Definovanie fazule pomocou singleton rozsah znamená, že kontajner vytvorí jednu inštanciu tejto fazule a všetky žiadosti o tento názov fazule vrátia rovnaký objekt, ktorý je uložený do pamäte cache. Akékoľvek úpravy objektu sa prejavia vo všetkých odkazoch na fazuľu. Ak nie je zadaný iný rozsah, je tento rozsah predvolenou hodnotou.

Vytvorme a Osoba subjekt ako príklad koncepcie rozsahov:

public class Osoba {private String name; // štandardný konštruktor, getre a setre}

Potom fazuľu definujeme pomocou singleton rozsahu pomocou @Rozsah anotácia:

@Bean @Scope ("singleton") public Person personSingleton () {return new Person (); }

Môžeme tiež použiť konštantu namiesto String hodnotu nasledujúcim spôsobom:

@Scope (hodnota = ConfigurableBeanFactory.SCOPE_SINGLETON)

Teraz pokračujeme v písaní testu, ktorý ukazuje, že dva objekty odkazujúce na rovnakú fazuľu budú mať rovnaké hodnoty, aj keď iba jeden z nich zmení svoj stav, pretože obidve odkazujú na rovnakú inštanciu fazule:

súkromný statický konečný reťazec NAME = "John Smith"; @Test public void givenSingletonScope_whenSetName_thenEqualNames () {ApplicationContext applicationContext = nový ClassPathXmlApplicationContext ("scopes.xml"); Osoba personSingletonA = (Osoba) applicationContext.getBean ("personSingleton"); Osoba personSingletonB = (Osoba) applicationContext.getBean ("personSingleton"); personSingletonA.setName (NAME); Assert.assertEquals (NAME, personSingletonB.getName ()); ((AbstractApplicationContext) applicationContext) .close (); }

The scopes.xml súbor v tomto príklade by mal obsahovať xml definície použitých bôbov:

3. Rozsah prototypov

Fazuľa s prototyp rozsah vráti inú inštanciu zakaždým, keď sa požaduje od kontajnera. Definuje sa nastavením hodnoty prototyp do @Rozsah anotácia v definícii fazule:

@Bean @Scope („prototyp“) public Person personPrototype () {return new Person (); }

Mohli by sme tiež použiť konštantu, ako sme to urobili pre singletonový rozsah:

@Scope (hodnota = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Teraz napíšeme podobný test ako predtým, ktorý ukazuje, že dva objekty vyžadujúce rovnaké meno fazule s prototypom rozsahu budú mať rôzne stavy, pretože už neodkazujú na rovnakú inštanciu fazule:

súkromný statický konečný reťazec NAME = "John Smith"; súkromný statický konečný reťazec NAME_OTHER = "Anna Jones"; @Test public void givenPrototypeScope_whenSetNames_thenDifferentNames () {ApplicationContext applicationContext = nový ClassPathXmlApplicationContext ("scopes.xml"); Osoba personPrototypeA = (Osoba) applicationContext.getBean ("personPrototype"); Osoba personPrototypeB = (Osoba) applicationContext.getBean ("personPrototype"); personPrototypeA.setName (NAME); personPrototypeB.setName (NAME_OTHER); Assert.assertEquals (NAME, personPrototypeA.getName ()); Assert.assertEquals (NAME_OTHER, personPrototypeB.getName ()); ((AbstractApplicationContext) applicationContext) .close (); } 

The scopes.xml súbor je podobný súboru uvedenému v predchádzajúcej časti a zároveň pridáva definíciu xml pre fazuľu pomocou prototyp rozsah:

4. Web Aware Rozsahy

Ako už bolo spomenuté, existujú štyri ďalšie rozsahy, ktoré sú k dispozícii iba v kontexte webových aplikácií. Tieto sa v praxi používajú menej často.

The žiadosť rozsah vytvorí inštanciu fazule pre jednu požiadavku HTTP, zatiaľ čo session sa vytvorí priestor pre reláciu HTTP.

The žiadosť rozsah vytvára inštanciu fazule pre životný cyklus a ServletContext a websocket rozsah to vytvára pre konkrétny WebSocket zasadanie.

Vytvorme triedu, ktorá sa použije na vytvorenie inštancie fazule:

verejná trieda HelloMessageGenerator {súkromná reťazcová správa; // štandardný getter a setter}

4.1. Rozsah žiadosti

Fazuľu môžeme definovať pomocou žiadosť rozsah pomocou @Rozsah anotácia:

@Bean @Scope (value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator requestScopedBean () {return new HelloMessageGenerator (); }

The proxyMode atribút je nevyhnutný, pretože v okamihu vytvorenia kontextu kontextu webovej aplikácie nie je aktívna požiadavka. Jar vytvorí proxy, ktoré sa má vložiť ako závislosť, a vytvorí inštanciu cieľovej fazule, keď je to v žiadosti potrebné.

Môžeme tiež použiť a @RequestScope zložená anotácia, ktorá slúži ako skratka pre vyššie uvedenú definíciu:

@Bean @RequestScope public HelloMessageGenerator requestScopedBean () {return new HelloMessageGenerator (); }

Ďalej môžeme definovať radič, ktorý má vložený odkaz na requestScopedBean. K rovnakej požiadavke musíme pristupovať dvakrát, aby sme mohli otestovať rozsahy špecifické pre web.

Ak zobrazíme správa pri každom spustení požiadavky vidíme, že sa hodnota resetuje na nulový, aj keď sa to v metóde neskôr zmení. Je to z dôvodu vrátenia inej inštancie fazule pre každú požiadavku.

@Controller verejná trieda ScopesController {@Resource (name = "requestScopedBean") HelloMessageGenerator requestScopedBean; @RequestMapping ("/ scopes / request") public String getRequestScopeMessage (konečný model modelu) {model.addAttribute ("previousMessage", requestScopedBean.getMessage ()); requestScopedBean.setMessage ("Dobré ráno!"); model.addAttribute ("currentMessage", requestScopedBean.getMessage ()); návrat "scopesExample"; }}

4.2. Rozsah relácie

Fazuľu môžeme definovať pomocou zasadanie rozsah podobným spôsobom:

@Bean @Scope (value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator sessionScopedBean () {return new HelloMessageGenerator (); }

Existuje aj vyhradená komponovaná anotácia, ktorú môžeme použiť na zjednodušenie definície fazule:

@Bean @SessionScope public HelloMessageGenerator sessionScopedBean () {return new HelloMessageGenerator (); }

Ďalej definujeme radič s odkazom na sessionScopedBean. Opäť musíme spustiť dve žiadosti, aby sme ukázali, že hodnota správa pole je rovnaké pre reláciu.

V takom prípade je hodnota zadaná po prvýkrát správa je nulový. Ale akonáhle sa to zmení, potom sa táto hodnota zachová pre ďalšie požiadavky, pretože sa vráti rovnaká inštancia fazule pre celú reláciu.

@Controller verejná trieda ScopesController {@Resource (name = "sessionScopedBean") HelloMessageGenerator sessionScopedBean; @RequestMapping ("/ scopes / session") public String getSessionScopeMessage (konečný model modelu) {model.addAttribute ("previousMessage", sessionScopedBean.getMessage ()); sessionScopedBean.setMessage ("Dobré popoludnie!"); model.addAttribute ("currentMessage", sessionScopedBean.getMessage ()); návrat "scopesExample"; }}

4.3. Rozsah aplikácie

The žiadosť rozsah vytvára inštanciu fazule pre životný cyklus a ServletContext.

Je to podobné ako s jedným rozsahom, ale pokiaľ ide o rozsah fazule, existuje veľmi dôležitý rozdiel.

Keď sú fazule žiadosť rovnaká inštancia fazule je zdieľaná vo viacerých aplikáciách založených na servlete, ktoré bežia v tej istej ServletContext, zatiaľ čo fazuľa s rozsahom jednotlivca je rozsahovaná iba pre jeden kontext aplikácie.

Vytvoríme fazuľu pomocou žiadosť rozsah:

@Bean @Scope (value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator applicationScopedBean () {return new HelloMessageGenerator (); }

Analogicky ako v prípade žiadosť a zasadanie rozsahy, môžeme použiť kratšiu verziu:

@Bean @ApplicationScope public HelloMessageGenerator applicationScopedBean () {return new HelloMessageGenerator (); }

Teraz vytvorme radič, ktorý odkazuje na túto fazuľu:

@Controller verejná trieda ScopesController {@Resource (name = "applicationScopedBean") HelloMessageGenerator applicationScopedBean; @RequestMapping ("/ scopes / application") public String getApplicationScopeMessage (konečný model modelu) {model.addAttribute ("previousMessage", applicationScopedBean.getMessage ()); applicationScopedBean.setMessage („Dobré popoludnie!“); model.addAttribute ("currentMessage", applicationScopedBean.getMessage ()); návrat "scopesExample"; }}

V tomto prípade hodnota správa raz stanovené v applicationScopedBean sa zachová pre všetky nasledujúce požiadavky, relácie a dokonca aj pre inú servletovú aplikáciu, ktorá bude pristupovať k tejto fazuli, za predpokladu, že beží v rovnakom ServletContext.

4.4. Rozsah WebSocket

Nakoniec vytvoríme fazuľu pomocou websocket rozsah:

@Bean @Scope (scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS) verejné HelloMessageGenerator websocketScopedBean () {vrátiť nový HelloMessageGenerator (); }

Fazuľa s rozsahom WebSocket je pri prvom prístupe uložená v priečinku WebSocket atribúty relácie. Rovnaká inštancia fazule sa potom vráti vždy, keď sa k tejto fazuli pristupuje počas celej WebSocket zasadanie.

Môžeme tiež povedať, že vykazuje singletonové správanie, ale je obmedzené na a ŽebSocket iba relácia.

5. Záver

Predviedli sme rôzne rozsahy fazule poskytnuté Springom a aké sú ich zamýšľané použitia.

Implementáciu tohto tutoriálu nájdete v projekte GitHub - jedná sa o projekt založený na Eclipse, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


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