Der einfachste Weg, Abhängigkeiten zu konfigurieren, ist mit der '.target' Eigenschaft. Dies erfordert, dass sich die Implementierungen mit einer identifizierenden Eigenschaft registrieren, z. B. impl=1
. und impl=2
.
@Component(property="impl=1")
public class MyServiceImpl1 implements MyService {
}
@Component(property="impl=2")
public class MyServiceImpl2 implements MyService {
}
Die Komponente dann aussehen könnte:
@Component
public class MyComponent {
@Reference(target="(impl=1)")
volatile MyService myService;
}
In diesem Fall, dass Sie nicht in der Lage sein, 1 oder 2 als Flag zu verwenden, aber Sie würden die Konfigurationseigenschaft für MyComponent
mit der ändern müssen Name myService.target
mit einem anderen Filter. (Dies wird mit standardisierten OSGi-Annotationen angezeigt.)
Wenn Sie auf einer Eigenschaft bestehen, die 1 oder 2 ist (nennen wir es select
) für MyComponent
dann ist es aufwendiger. Zuerst haben wir das Problem, zufrieden zu sein. Sollte MyComponent zufrieden sein, wenn es gemäß der ausgewählten Eigenschaft impl 1 benötigt wird, aber nur 2 verfügbar ist? Wenn das in Ordnung ist dann die folgende viel kompliziertere Lösung
@Designate(ocd=Config.class)
@Component(property = "select=1")
public class MyComponent {
static Class<?> types [] = {
MyServiceImpl1.class,
MyServiceImpl2.class,
};
@interface Config {
int select() default 1;
}
@Reference(target="(|(impl=1)(impl=2))")
volatile List<MyService> candidates;
volatile MyService selected;
@Activate
@Modify
void changed(Config config) {
Class<?> type = types[config.select()];
Optional<MyService> service = candidates.
stream().
filter(type::isInstance).
findFirst();
this.service = service.isPresent() ? service.get() : null;
}
}
arbeiten sollten Sie sehen es ist generell eine schlechte Idee für eine Komponente zu starten ihre eigenen Abhängigkeiten zu behandeln. Ich bin daher neugierig auf dein Szenario in der realen Welt.
Ich finde es immer sehr umständlich und schwierig, Designs zu pflegen, bei denen Komponenten wählerisch sind, auf wen sie sich beziehen. Es ist manchmal unvermeidlich, aber in allgemeinen Lösungen, wo MyServiceImpl2
und MyServiceImpl1
entscheiden, zu registrieren oder nicht basierend auf einer bestimmten Bedingung die Realität besser widerspiegeln.
Also die große Frage, die ich habe, was die 1 oder 2 Eigenschaft in der realen Welt widerspiegelt? Kann dies nicht als Serviceabhängigkeit modelliert werden?
(Haftungsausschluss: Code nicht getestet und keine Fehlerbehandlung darin)
Danke Alexandre. Ich benutze Apache Felix Framework. Ich habe die Frage mit diesen Informationen aktualisiert. – sdm
Apache Felix ist eine OSGi-Framework-Implementierung, aber wie veröffentlichen Sie Ihre Komponente? Verwenden einer Activator- und registerService-Methode, durch Annotation, ...? –
Btw, ich denke nicht, dass dies ohne die Verwendung von "Low-Level" API möglich ist –