4

OSGi 環境で実行されている (つまり、OSGi HttpServiceに登録されている) HttpServlet が、そのタスクを実行するためにいくつかの OSGi サービスを呼び出したいと思うのは当然のことです。問題は、サーブレット内でこれらの OSGi サービスへの参照を取得する方法です。

1 つの方法は、次のように OSGi HttpService に登録されている HttpServlet インスタンスに依存関係を注入することです。

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

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

OSGi 以外の環境では、サーブレットのライフサイクルが Web コンテナーによって管理され、後で作成されるサーブレット インスタンスにサービス参照が挿入されないため、これが有効なアプローチであるかどうかはわかりません。

OSGi HttpService の実装としてPAX Webを使用する場合、これを解決する別の方法があります。PAX Web は、OSGi BundleContext を特別な属性「osgi-bundlecontext」として ServletContext にエクスポートします。BundleContext を使用して、必要なサービス参照を取得できます。

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")
}

ただし、このアプローチはかなり見苦しく、OSGi HttpService の具体的な実装に結び付けられます。この問題に対する他の (そしておそらくより良い) 解決策を知っていますか?

4

3 に答える 3

2

古い投稿かもしれませんが、すでに答えが得られている可能性があります.felixまたはOSGiコンテナを自分で起動していますか。その場合は、バンドル コンテキストを属性としてサーブレット コンテキストに設定できます。

PAX で http サービスを使用する際の何が問題なのですか。最終的に、スレッド管理やその他の側面は、この http サービスを実行するサーブレット コンテナーによって処理されます。

于 2011-03-02T11:29:59.927 に答える
2

あなたが示したように、サービスへの依存関係にセッターを使用すると、OSGiの外でも機能します。他の依存性注入メカニズムを使用する必要があるだけです。何もない場合は、JNDI ルックアップを使用して、またはサーブレット コンテキストからサーブレットを初期化するサブクラスを提供できます。

public class MyServlet_AdapterForMissingDI extends MyServlet{

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

}

要点は、 を注入できる DI 機能がある場合はsetFooService、OSGi などで同じサーブレットを使用できます。そうでない場合 (そしてこのケースをサポートしたい場合) は、アダプターを提供します。

これに関連して、オブジェクトの依存関係を構成するための Felix SCR と、サーブレットを HttpService にフックする Pax Web Extender Whiteboard を確認してください。

具体的には、SCR とホワイトボードがない場合、後で fooService が使用できなくなった場合や、サーブレットの後に HttpService が開始された場合について考える必要があります。このような場合、サーブレットは、バンドルがガベージ コレクションされるのを防ぐデッド サービスへの参照を持つか、またはサーブレットが HttpService に登録されません。

更新:これは、サーブレットの 1 つに使用する SCR 記述子です。SCR は、サーブレットのインスタンス化、ライフサイクル、登録 (ホワイトボード経由)、および依存関係を処理します。サーブレットには OSGi 固有のコードはありません。もう BundleActivator は必要ありません (SCR はすべてのサービスを登録します):

<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>

サーブレットの依存関係はreferenceタグで指定されます。SCR は、サービスの検索とバインドを行います。

于 2009-06-17T07:50:58.893 に答える
-1

サービスを何らかのオブジェクトに注入し、それをサーブレットによってクエリすることができます。

于 2009-06-16T19:14:07.547 に答える