WebHU - Programozási kérdések és válaszok

Injektálja be az objektumot a telepített REST szolgáltatásba

REST API-t fejlesztek egy Osgi csomagban. A Jersey-t használom arra, hogy a szolgáltatásokat egy mólókonténerbe telepítsem, Javax servletekkel minden REST szolgáltatásokkal rendelkező osztályhoz.

Minden osztálynak van egy ilyen attribútuma

Private DBInterface dbInterface;

Beállítókkal és getterekkel, és be kell injektálnom az objektumot egy másik csomagból, miután a szolgáltatás üzembe helyezte (futás közben). Szóval tud valaki valami módszert rá?

Előre is köszönöm.

PD: Szeretném megtenni anélkül, hogy a szolgáltatást egyedinek nyilvánítanám, így minden REST-kérésre a szolgáltatás egy másik példánya válaszol (tényleges állapot nélküli REST)

Frissítés: A web.xml kód, amelyet a szolgáltatás telepítéséhez használok:

<servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
        <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.config.property.classnames</param-name>
        <param-value>com.mypackage.MyServiceClass</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
19.08.2013

  • Mi a pontos oka annak, hogy nem akarja a szolgáltatást szinglinek nyilvánítani? Azt hiszem, regisztrálhat objektumokat Jersey-be, így REST szolgáltatásként lesznek biztosítva. Nincs lehetőséged gyárat vagy valamit meghatározni, ami egy objektum példányosítására szolgál minden egyes kérésnél. Egy másik kérdés: Hogyan történik a másik kötegben lévő objektum példányosítása? Milyen technológiát vagy mechanizmust használ a példányosításhoz? Aktivátorban vagy speciális technológiával csinálod? Mi az az esemény, ami miatt a másik köteg példányosítja az objektumot? 20.08.2013
  • Aktivátor igen. Példányosítom a másik objektumot, amikor az azt tartalmazó köteg elindul, az aktivátorban az objektum be van állítva, majd be kell injektálni a REST szolgáltatásba. Azt hittem, lehet mondani ennek a szolgáltatásnak, hogy vigye el az objektumot, vagy használja a Jersey-t, a mólót vagy egy másik csomagot vagy könyvtárat az objektum beszúrására minden alkalommal, amikor a szolgáltatás példányosodik. 21.08.2013
  • Miért akarja többször példányosítani a szolgáltatást? Miért nem jó, ha az egyes kéréseknél a különböző részt példányosítjuk lokális változóként a függvényünkön belül? Hogyan regisztrálja szolgáltatását Jerseyben? Webapp web.xml-ben konfigurálja, vagy HTTP-szolgáltatással regisztrálja programozottan? Az az érzésem, hogy a megoldás meglehetősen egyszerű lenne számodra, de jó lenne egy kicsit többet tudni a válasz előtt. 21.08.2013
  • A helyzet az, hogy mivel ez egy REST szolgáltatás, a hatókör kérésre vonatkozik, ami azt jelenti, hogy az adott szolgáltatás minden kérésére a szolgáltatás egy másik példánya válaszol. A web.xml-ben javax servlet segítségével konfigurálom a telepítést, a kérdést web.xml kóddal frissítem. 21.08.2013

Válaszok:


1

Először is regisztrálnia kell az objektumot a másik csomagaktivátorban OSGi szolgáltatásként. Ebben az esetben szinte mindenhonnan elérheti.

A másik kérdés: hogyan lehet hozzáférni a másik oldalról? Sok lehetőség van, van, amelyik jobb, van, amelyik rosszabb.

Egy egyszerű, de nem igazán szép megoldás:

Bundle bundle = FrameworkUtil.getBundle(this.getClass());
// Getting the service and using it based on the bundle

Ezzel a megoldással az a probléma, hogy minden kéréshez le kell szerezni az OSGi szolgáltatást az OSGi szolgáltatásnyilvántartásból szűrők alapján, és a függvényhívás után törölni kell, felesleges többlet.

A ServiceTrackeren alapuló megoldás:

Ha szolgáltatáskövetőt használ, azzal a problémával kell szembenéznie, hogy valahol ki kell nyitnia és be kell zárnia. Megoldás lehet a konstruktorban való nyitás, de a pihenőórán nem találsz olyan helyet, ahol bezárhatod. Megoldás lehet, hogy létrehozol egy Servlet figyelőt, ott megnyitod és bezárod a nyomkövetőt, és beviszed a szolgáltatáskövetőt a servlet kontextus attribútumtérképébe. A REST függvényben elérheti a szervlet kontextust, és minden hívásban megkaphatja a szolgáltatáskövetőt, mint a tracker.getService(). Ez a funkció visszaadja a szükséges objektumot vagy nullát, ha még nincs regisztrálva.

Megoldás, amely nem teszi szükségessé az OSGi-vel kapcsolatos kódot a REST osztályba:

Előfordulhat, hogy nem szeretné használni a ServiceTracker-t a REST kódban, mivel nem akar az OSGi-től függeni. Ebben az esetben használhat egy nagyon egyszerű könyvtárat, amelyet megvalósítottam :). A következő címen érhető el: https://github.com/everit-org/osgi-servicereference .

A módszertan ugyanaz. Írsz egy Listenert, amely: - ServiceReference-t hoz létre - Meghívod a serviceReference getProxtInstance-jét a ServletContextbe - A REST függvényben megadott interfész alapján megkapod a proxy objektumot, és meghívod a rajta lévő metódusokat.

A ServiceReference a Blueprint megvalósítás részeként valósult meg. Ezért ugyanúgy működik, mint a címke egy XML-tervfájlban. Példányosíthat egy szolgáltatási hivatkozást, és megnyithatja azt (a megnyitás után az OSGi szolgáltatások nyomon követhetők). A getProxyInstance metódussal kaphat egy objektumot, amely megvalósítja a szükséges (Ön által biztosított) interfészeket.

Amikor függvényhívás történik az objektumhoz az interfész alapján:

  • Ha elérhető egy OSGi szolgáltatás, a funkcióhívás át lesz delegálva arra a szolgáltatásra
  • Ha nem érhető el OSGi szolgáltatás, a függvényhívás egy időtúllépésig tart (egyszerű thread.wait). Ha van OSGi szolgáltatás az időtúllépés előtt, a funkcióhívás delegálásra kerül. Ha nem, akkor a rendszer egy ServiceUnavailableException kivételt dob. Az időtúllépési viselkedést felülírhatja egy másik időtúllépés-kezelő beállításával a ServiceReference objektumhoz.

A normál függvényhívás a következő:

hívó -> OSGiService.function

A ServiceReference Proxy objektumon keresztüli függvényhívás így néz ki:

hívó -> ServiceReference.proxyObject -> OSGiService.function (ha az OSGiService elérhető)

Most a gyakorlatban a megoldás:

Írjon egy figyelőt a webalkalmazáshoz:

private Reference reference;

@Override
public void contextInitialized(final ServletContextEvent sce) {
    ServletContext servletContext = sce.getServletContext();
    BundleContext bundleContext = (BundleContext) servletContext.getAttribute("osgi-bundlecontext");

    try {
        Filter filter = bundleContext.createFilter("(objectClass=" + MyInterface.class.getName() + ")");

        // MyInterface is the interface the OSGi service implements (there can be multiple) and the timeout until function calls will wait is 5s.
        reference = new Reference(bundleContext, new Class<?>[] { MyInterface.class }, filter, 5000);

        // Opening the reference is necessary to track services
        reference.open();

        // Taking the proxy object into the servlet context attributes
        servletContext.setAttribute("myService", reference.getProxyInstance());
    } catch (InvalidSyntaxException e) {
        LOGGER.error(e.getMessage(), e);
    }
}

@Override
public void contextDestroyed(final ServletContextEvent sce) {
    if (reference != null) {
        reference.close();
        sce.getServletContext().removeAttribute("myService");
    }
}

Miután rendelkezik ezzel a figyelővel, a következőhöz hasonló proxy objektumot mindenhol megkaphatja a kódokban (ahol elérheti a servlet kontextust):

MyInterface myService = servletContext.getAttribute("myService");
myService.foo();
21.08.2013
  • Érdekel bennünket az Ön által javasolt legutóbbi megoldás, de nehezen értjük meg a könyvtár működését. Az Ön által létrehozott referenciapéldány megkapja a http kéréseket a szolgáltatásokhoz, majd megvárja, amíg létrejön a szolgáltatáspéldány, vagy valami hasonló? 22.08.2013
  • frissítette a választ, hogy több információhoz jusson. Ha valami nem világos, kérem jelezze. Azt hiszem, ezt a stackoverflow kérdést példának fogom linkelni a ServiceReference oldal readme fájljából. Kérjük, ellenőrizze a README és a Reference osztály javadoc-ját is további információkért. 22.08.2013
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..