2012-04-27 10 views
6

Quando uso un riferimento in DS, posso specificare un obiettivo che mi consentirà di restringere quale istanza di servizio desidero. Il problema è che tutti gli esempi mostrano query statiche che devono essere eseguite al momento del codice. C'è un modo per fare una query dinamica (magari inserire una proprietà da Configuration Admin)?Query di destinazione dinamiche in OSGi con DS

Se DS non supporta questo c'è un altro framework di iniezione delle dipendenze OSGi (blueprint, iPojo, ecc.) Che supporterà questo?

risposta

7

È sempre possibile utilizzare l'attributo target del riferimento per peform un filtro di primo livello. Se il metodo di bind ha la firma

void <method-name>(<parameter-type>, Map); 

Quindi è possibile eseguire qualsiasi filtro dinamico sulla mappa che contiene le proprietà dei servizi. Se il filtro non corrisponde, è possibile ignorare quel componente (per il momento).

In alternativa, poiché la configurazione del componente può contenere il filtro di destinazione del riferimento, è possibile modificare la configurazione del componente per modificare il filtro di destinazione.

+0

Ho giocato con il tuo primo suggerimento e sembra che si adatta perfettamente ai nostri bisogni. Grazie. – rancidfishbreath

5

Io uso il seguente trucco. Se si specifica un attributo "target" sul riferimento del servizio ma si lascia il suo valore come stringa vuota , quindi una proprietà del componente con lo stesso nome ma un suffisso ".target" verrà utilizzato in fase di esecuzione.

Nell'esempio seguente, seleziono la mia sorgente JDBC in modo dinamico tramite un file .cfg nel mio contenitore Karaf. La proprietà "datasourcefactory.target" viene iniettata automaticamente nell'attributo "target" del riferimento "datasourcefactory".

Avvertenza: non so se questo trucco è ufficialmente supportato o solo una funzione SCR Felix. Volevo vedere questo nelle specifiche per vedere se è menzionato ... +1 a qualsiasi commento che chiarisca la sua legalità!

@Component(
      name = "...", 
      specVersion = "1.1", 
      policy = ConfigurationPolicy.REQUIRE, 
      metatype = true 
    ) 
    @Property(name = "dataSourceFactory.target", 
      value = "", 
      label = "dataSourceFactory target", 
      description = "An OSGi service filter to select the data source provider. "+ 
        "For example: '(&(osgi.jdbc.driver.name=derby)(objectClass=org.osgi.service.jdbc.DataSourceFactory))' where 'derby' is the important bit and the rest is boilerplate. "+ 
        "See DataSourceFactory.OSGI_JDBC_DRIVER_(NAME,CLASS,VERSION)." 
    ) 
    @Reference(
      name = "dataSourceFactory", 
      referenceInterface = org.osgi.service.jdbc.DataSourceFactory.class, 
      cardinality = ReferenceCardinality.MANDATORY_UNARY, 
      target = "", // must be overwritten by configuration property named "dataSourceFactory.target" 
      bind = "bindDataSourceFactory", 
      unbind = "unbindDataSourceFactory" 
    ) 
+5

La sezione 112.3.4 del servizio OSGi 4.2 menziona: * "Il deployer può anche impostare la proprietà di destinazione stabilendo una configurazione per il componente che imposta il valore della proprietà di destinazione, consentendo al deployer di sovrascrivere la proprietà di destinazione nel descrizione del componente. "* - questa è una funzione ufficiale. –

+0

Grazie, @ BjörnPollex! –