6 Stimmen

Dynamische Zielabfragen in OSGi mit DS

Wenn ich in DS eine Referenz verwende, kann ich ein Ziel angeben, das es mir ermöglicht, die Service-Instanz, die ich möchte, genauer zu definieren. Das Problem ist, dass alle Beispiele statische Abfragen zeigen, die zur Codezeit durchgeführt werden müssen. Gibt es eine Möglichkeit, eine dynamische Abfrage durchzuführen (vielleicht eine Eigenschaft von Configuration Admin zu verwenden)?

Wenn DS dies nicht unterstützt, gibt es ein anderes OSGi-Abhängigkeitseinspritzungsframework (Blueprint, iPojo usw.), das dies unterstützt?

7voto

BJ Hargrave Punkte 9136

Sie können immer das target-Attribut der Referenz verwenden, um einen Filter der ersten Ebene durchzuführen. Wenn Ihre Bindungsmethode die Signatur hat

void (, Map);

Dann können Sie jeden dynamischen Filter über die Map ausführen, die die Eigenschaften der Dienste enthält. Wenn der Filter nicht übereinstimmt, können Sie dieses Komponente ignorieren (zunächst).

Alternativ können Sie, da die Konfiguration der Komponente den Ziel-Filter der Referenz enthalten kann, die Konfiguration der Komponente ändern, um den Ziel-Filter zu ändern.

5voto

Chris Dolan Punkte 8777

Ich verwende den folgenden Trick. Wenn Sie ein "target"-Attribut auf dem Servicereferenz spezifizieren, aber seinen Wert als leeren String belassen, wird zur Laufzeit eine Komponenteneigenschaft mit demselben Namen, aber einem Suffix ".target" verwendet.

In dem untenstehenden Beispiel wähle ich meine JDBC-Quelle dynamisch über eine .cfg-Datei in meinem Karaf-Container aus. Die Eigenschaft "datasourcefactory.target" wird automatisch in das "target"-Attribut des "datasourcefactory"-Verweises injiziert.

Warnung: Ich weiß eigentlich nicht, ob dieser Trick offiziell unterstützt wird oder nur ein Feature von Felix SCR ist. Ich wollte das schon immer im Spezifikation nachschlagen, um zu sehen, ob es erwähnt wird... +1 für jeden Kommentar, der seine Rechtmäßigkeit erläutert!

    @Component(
            name = "...",
            specVersion = "1.1",
            policy = ConfigurationPolicy.REQUIRE,
            metatype = true
    )
    @Property(name = "dataSourceFactory.target",
            value = "",
            label = "dataSourceFactory target",
            description = "Ein OSGi-Servicefilter zur Auswahl des Datenquellenanbieters. "+
                    "Zum Beispiel: '(&(osgi.jdbc.driver.name=derby)(objectClass=org.osgi.service.jdbc.DataSourceFactory))' wobei 'derby' der wichtige Teil ist und der Rest Standardcode ist. "+
                    "Siehe DataSourceFactory.OSGI_JDBC_DRIVER_(NAME,CLASS,VERSION)."
    )
    @Reference(
            name = "dataSourceFactory",
            referenceInterface = org.osgi.service.jdbc.DataSourceFactory.class,
            cardinality = ReferenceCardinality.MANDATORY_UNARY,
            target = "", // muss überschrieben werden durch Konfigurationseigenschaft mit dem Namen "dataSourceFactory.target"
            bind = "bindDataSourceFactory",
            unbind = "unbindDataSourceFactory"
    )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X