Egyéni hatókör tavasszal

1. Áttekintés

A dobozon kívül a Spring két szokásos babszemkört biztosít ("szingli" és "prototípus"), amely bármely tavaszi alkalmazásban használható, valamint további három babszem ("kérés", "ülés", és „GlobalSession”) csak web-tudatos alkalmazásokban használható.

A szokásos bab hatóköröket nem lehet felülbírálni, és általában rossz gyakorlatnak számít a webtudatos hatókörök felülbírálása. Előfordulhat azonban, hogy van olyan alkalmazása, amely a megadott hatóköröktől eltérő vagy kiegészítő képességeket igényel.

Például, ha több bérlőből álló rendszert fejleszt, akkor érdemes minden bérlőhöz külön példányt adnia egy adott babról vagy babkészletről. A Spring mechanizmust biztosít az egyedi forgatókönyvek létrehozásához az ilyen forgatókönyvekhez.

Ebben a gyors bemutatóban bemutatjuk hogyan hozhat létre, regisztrálhat és használhat egyedi hatókört egy Spring alkalmazásban.

2. Custom Scope osztály létrehozása

Egyéni hatókör létrehozása érdekében végre kell hajtanunk a Hatály felület. Ennek során nekünk is meg kell tennünk gondoskodjon arról, hogy a megvalósítás menetes legyen mert a hatóköröket egyszerre több babgyár használhatja.

2.1. A hatókörbe tartozó objektumok és visszahívások kezelése

Az egyik első szempont, amelyet figyelembe kell venni egy szokás megvalósításakor Hatály osztályban tárolhatja és kezelheti a hatókörbe tartozó tárgyakat és a megsemmisítési visszahívásokat. Ez történhet például egy térkép vagy egy dedikált osztály használatával.

Ebben a cikkben ezt szálkamentes módon fogjuk megtenni szinkronizált térképek segítségével.

Kezdjük meghatározni egyéni hatókör osztályunkat:

public class TenantScope megvalósítja a Scope {private Map scopedObjects = Collections.synchronizedMap (új HashMap ()); privát térkép hävesztési visszahívások = Collections.synchronizedMap (új HashMap ()); ...}

2.2. Objektum lekérése a hatókörből

Ha egy objektumot név szerint szeretnénk lekérni a hatókörünkből, hajtsuk végre a getObject módszer. Ahogy a JavaDoc állítja, ha a megnevezett objektum nem létezik a hatókörben, ennek a metódusnak új objektumot kell létrehoznia és visszaadnia.

Megvalósításunk során ellenőrizzük, hogy a megnevezett objektum szerepel-e a térképünkön. Ha igen, akkor visszaküldjük, és ha nem, akkor a ObjectFactory új objektum létrehozásához adja hozzá a térképünkhöz és adja vissza:

@Orride public Object get (String name, ObjectFactory objectFactory) {if (! ScopedObjects.containsKey (name)) {scopedObjects.put (név, objectFactory.getObject ()); } return scopedObjects.get (név); }

A. Által meghatározott öt módszer közül Hatály felület, csak a kap módszer szükséges a teljes megvalósításhoz a leírt viselkedés. A másik négy módszer választható, és dobhat UnsupportedOperationException ha nincs szükségük vagy nem tudják támogatni a funkciókat.

2.3. Destruction Callback regisztrálása

Meg kell valósítanunk a registerDestructionCallback módszer. Ez a módszer visszahívást biztosít, amelyet akkor kell végrehajtani, amikor a megnevezett objektum megsemmisül, vagy ha magát a hatókört megsemmisíti az alkalmazás:

@Orride public void registerDestructionCallback (Karakterlánc neve, Futható visszahívás) {destrCallbacks.put (név, visszahívás); }

2.4. Objektum eltávolítása a hatókörből

Ezután hajtsuk végre a eltávolítani metódus, amely eltávolítja a megnevezett objektumot a hatókörből, és törli a regisztrált megsemmisítési visszahívását is, visszaküldve az eltávolított objektumot:

@Orride public Object remove (String name) {destrCallbacks.remove (name); return scopedObjects.remove (név); }

Vegye figyelembe, hogy a hívó felelőssége a visszahívás tényleges végrehajtása és az eltávolított objektum megsemmisítése.

2.5. Beszélgetési azonosító lekérése

Most hajtsuk végre a getConversationId módszer. Ha az Ön hatóköre támogatja a beszélgetésazonosító fogalmát, akkor itt adja vissza. Ellenkező esetben az egyezmény a visszatérés nulla:

@Orride public String getConversationId () {return "bérlő"; }

2.6. Környezeti objektumok megoldása

Végül hajtsuk végre a ResolContextualObject módszer. Ha a hatóköre több kontextuális objektumot támogat, akkor mindegyiket társítja egy kulcsértékhez, és a megadott objektumnak megfelelő objektumot adja vissza kulcs paraméter. Ellenkező esetben az egyezmény a visszatérés nulla:

@Orride public Object ResolContextualObject (String key) {return null; }

3. Az egyedi hatókör regisztrálása

Ahhoz, hogy a Spring konténer megismerje új hatókörét, meg kell regisztrálja a registerScope módszer a ConfigurableBeanFactory példa. Vessünk egy pillantást a módszer definíciójára:

void registerScope (String hatókörNév, Hatókör hatókör);

Az első paraméter, hatókörNév, a hatókör egyedi nevével történő azonosítására / megadására szolgál. A második paraméter, hatálya, a szokás tényleges példánya Hatály regisztrálni és használni kívánt megvalósítást.

Hozzunk létre egy egyéni BeanFactoryPostProcessor és regisztrálja az egyedi hatókörünket az a használatával ConfigurableListableBeanFactory:

public class TenantBeanFactoryPostProcessor implementálja a BeanFactoryPostProcessor {@Override public void postProcessBeanFactory (ConfigurableListableBeanFactory factory) dobja a BeansException {factory.registerScope ("bérlő", új TenantScope ()); }}

Most írjunk egy Spring konfigurációs osztályt, amely betölti a sajátunkat BeanFactoryPostProcessor végrehajtás:

@Configuration public class TenantScopeConfig {@Bean public static BeanFactoryPostProcessor beanFactoryPostProcessor () {return new TenantBeanFactoryPostProcessor (); }}

4. Az Egyéni hatókör használata

Most, hogy regisztráltuk az egyedi hatókörünket, bármely babunkra alkalmazhatjuk, ugyanúgy, mint bármely más bab esetében, amely a szingli (az alapértelmezett hatókör) - a @Scope feliratozás és egyedi hatókörünk megadása név szerint.

Hozzunk létre egy egyszerű BérlőBean osztály - egy pillanat alatt kihirdetjük az ilyen típusú bérlői babot:

public class TenantBean {private final String name; public TenantBean (karakterlánc neve) {this.name = név; } public void sayHello () {System.out.println (String.format ("Üdvözlet% s típustól% s a% s típustól", ez a név, ez a. }}

Ne feledje, hogy nem az osztály szintjét használtuk @Összetevő és @Scope jegyzetek erről az osztályról.

Most adjunk meg néhány bérlői hatókörű babot egy konfigurációs osztályban:

@Configuration public class TenantBeansConfig {@Scope (scopeName = "bérlő") @Bean public TenantBean foo () {return new TenantBean ("foo"); } @Scope (scopeName = "tenant") @Bean public TenantBean bar () {return new TenantBean ("bar"); }}

5. Az egyedi hatókör tesztelése

Írjunk egy tesztet az egyéni hatókör-konfiguráció gyakorlásához egy ApplicationContext, regisztrálja a mi Konfiguráció osztályok és a bérlői hatókörű babunk beszerzése:

@Test public final void whenRegisterScopeAndBeans_thenContextContainsFooAndBar () {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (); próbáld ki a {ctx.register (TenantScopeConfig.class); ctx.register (TenantBeansConfig.class); ctx.refresh (); TenantBean foo = (TenantBean) ctx.getBean ("foo", TenantBean.class); foo.sayHello (); TenantBean bar = (TenantBean) ctx.getBean ("bar", TenantBean.class); bar.sayHello (); Map foos = ctx.getBeansOfType (TenantBean.class); assertThat (foo, not (egyenlőTo (bar))); assertThat (foos.size (), egyenlőTo (2)); assertTrue (foos.containsValue (foo)); assertTrue (foos.containsValue (bar)); BeanDefinition fooDefinition = ctx.getBeanDefinition ("foo"); BeanDefinition barDefinition = ctx.getBeanDefinition ("bar"); assertThat (fooDefinition.getScope (), equalTo ("bérlő")); assertThat (barDefinition.getScope (), equalTo ("bérlő")); } végül {ctx.close (); }}

És tesztünk eredménye:

Üdvözlet az org.baeldung.customscope.TenantBean típusú foo-ból. Üdvözlet az org.baeldung.customscope.TenantBean típusú sávból

6. Következtetés

Ebben a gyors bemutatóban megmutattuk, hogyan lehet meghatározni, regisztrálni és használni az egyéni hatókört tavasszal.

Az egyéni hatókörökről a Spring Framework Reference-ben olvashat bővebben. Megtekintheti Spring különféle megvalósításait is Hatály osztályok a Spring Framework tárházban a GitHubon.

Szokás szerint a cikkben használt kódmintákat megtalálhatja a GitHub projekten.