Frage

Es scheint natürlich, dass ein HttpServlet in OSGi-Umgebung ausgeführt wird (dh in OSGi registriert Httpservice ) möchte einige OSGi-Services nennen es Aufgaben zu erfüllen. Die Frage ist, wie Verweise auf diesen OSGi Service innerhalb des Servlet zu erhalten.

Eine Möglichkeit wäre, Abhängigkeiten in die HttpServlet Instanz zu injizieren, die dem OSGi registriert wird Httpservice wie folgt aus:

MyServlet servlet = new MyServlet();
servlet.setFooService(fooService);

httpService.registerServlet("/myservlet", servlet, initparams, context);

Ich bin nicht sicher, ob dies ein gültiger Ansatz ist, da in nicht-OSGi-Umgebung des Servlet-Lebenszyklus von den Web-Containern verwaltet wird und damit der Dienstverweis wäre für die Servlet-Instanzen nicht später erstellt injiziert werden.

Es gibt einen anderen Weg, dies zu lösen, wenn PAX Web als Implementierung des OSGi Httpservice. PAX Web exportiert die OSGi Bundlecontext in die ServletContext als besonderes Attribut „OSGi-Bundlecontext“. Die Bundlecontext kann dann dazu verwendet werden, die notwendig Service Referenzen zu erhalten:

public void init(ServletConfig servletConfig) throws ServletException {

    ServletContext context = servletConfig.getServletContext()
    BundleContext bundleContext = 
        (BundleContext) context.getAttribute("osgi-bundlecontext");

    ServiceReference serviceRef =
         bundleContext.getServiceReference("com.foo.FooService")
}

Allerdings ist dieser Ansatz eher hässlich und Beziehungen Sie auf eine konkrete Umsetzung des OSGi Httpservice. Wissen Sie andere (und möglicherweise besser) Lösung für dieses Problem?

War es hilfreich?

Lösung

Wenn Sie einen Setter für die Abhängigkeit von dem Dienst zu nutzen, wie Sie gezeigt haben, kann es auch außerhalb von OSGi arbeiten. Sie brauchen nur einen anderen Dependency Injection-Mechanismus zu verwenden. Wenn es keine gibt, können Sie eine Unterklasse zur Verfügung stellen, die das Servlet mit JNDI-Lookups oder aus dem Servlet-Kontext initialisiert.

public class MyServlet_AdapterForMissingDI extends MyServlet{

    public void init(ServletConfig config){
        setFooService(getItFromSomewhere());
    }

}

Der Punkt ist, dass, wenn Sie DI-Fähigkeiten haben, die setFooService injizieren kann, kann man einfach die gleiche Servlet in OSGi verwenden und an anderer Stelle, wenn Sie dies nicht tun (und immer noch wollen, um diesen Fall unterstützen), bieten Sie einen Adapter.

über einen entsprechenden Hinweis Besuche Felix SCR Ihre Objektabhängigkeiten zu konfigurieren und Pax Web Extender Weiße Tafel, die Versorgung mit dem Httpservice von Einhaken Servlets in Anspruch nimmt.

Im Einzelnen ohne SCR und Whiteboard, müssen Sie über den Fall denken, wenn die fooService später nicht mehr verfügbar sind, oder der Httpservice nach dem Servlet wird gestartet. In diesen Fällen würde Ihr Servlet einen Verweis auf einen toten Dienst hat, das Bündel davon, dass die Garbage Collection, oder Servlets mit dem Httpservice nicht registriert verhindert.

Update: Hier ist der SCR-Descriptor ich für eine meiner Servlets verwenden. SCR Griffe Servlet Instanziierung, Lebenszyklus, Registrierung (via Whiteboard) und Abhängigkeiten. Es gibt keinen OSGi-spezifischen Code in dem Servlet. Es gibt nicht einmal die Notwendigkeit einer Bundle mehr (SCR registriert alle Dienste):

<component name="oracle.statusServlet" >
<implementation class="mypackage.DataSourceStatusServlet"/>
<property name="service.description" value="Oracle DataSource status servlet" />
<property name="alias" value="/OracleDataSourceStatus" />
<property name="servlet-name" value="Oracle DataSource status servlet" />
<service>
    <provide interface="javax.servlet.Servlet" />
</service>
    <reference name="DATASOURCES" 
            interface="javax.sql.DataSource"
            cardinality="0..n" policy="dynamic" 
            bind="bindDataSource" unbind="unbindDataSource"/>

</component>

Die Abhängigkeiten für das Servlet in dem reference Tag angegeben. SCR wird das Service-Lookup und bindend.

Andere Tipps

Auch eine alte Post und Sie bereits haben könnten die Antwort bekommen .. Starten Sie felix oder was auch immer OSGi-Container selbst. Wenn das der Fall ist, können Sie das Bündel Kontext als ein Attribut auf den Servlet-Kontext gesetzt.

Was ist falsch in mit einem HTTP-Dienst von PAX. schließlich das Thread-Management und andere Aspekte werden betreut von den Servlet-Containern, in dem Sie den http-Dienst ausführen.

Sie können die Dienste in ein Objekt injizieren, die dann von dem Servlets abgefragt wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top