2012-04-27 7 views
6

Cuando uso una referencia en DS, puedo especificar un objetivo que me permita restringir qué instancia de servicio que quiero. El problema es que todos los ejemplos muestran consultas estáticas que deben hacerse en el momento del código. ¿Hay alguna manera de hacer una consulta dinámica (tal vez obtener una propiedad de Configuration Admin)?Consultas de destino dinámicas en OSGi con DS

Si DS no es compatible, ¿existe otro marco de inyección de dependencias OSGi (blueprint, iPojo, etc.) que lo respalde?

Respuesta

7

Siempre puede usar el atributo de destino de la referencia para formar un filtro de primer nivel. El si su método de enlace tiene la firma

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

continuación, puede ejecutar cualquier filtro dinámico sobre el mapa que contiene las propiedades de servicios. Si el filtro no coincide, puede ignorar ese componente (por el momento).

Como alternativa, dado que la configuración del componente puede contener el filtro objetivo de la referencia, puede modificar la configuración del componente para alterar el filtro objetivo.

+0

He jugado con su primera sugerencia y parece que se ajustará perfectamente a nuestras necesidades. Gracias. – rancidfishbreath

5

Utilizo el siguiente truco. Si especifica un atributo "objetivo" en la referencia de servicio pero deja su valor como cadena vacía, se usará una propiedad de componente con el mismo nombre pero con el sufijo ".target" en tiempo de ejecución.

En el ejemplo a continuación, selecciono mi fuente JDBC dinámicamente a través de un archivo .cfg en mi contenedor Karaf. La propiedad "datasourcefactory.target" se inyecta automáticamente en el atributo "objetivo" de la referencia "datasourcefactory".

Advertencia: en realidad no sé si este truco es oficialmente compatible o simplemente una característica SCR de Felix. He querido buscar esto en la especificación para ver si se menciona ... +1 a cualquier comentario que aclare su legalidad.

@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 sección 112.3.4 del Compendio de servicios de OSGi 4.2 menciona: * "El implementador también puede establecer la propiedad de destino estableciendo una configuración para el componente que establece el valor de la propiedad de destino. Esto permite que el implementador anule la propiedad de destino en el descripción del componente. "* - esta es una función oficial. –

+0

Gracias, @ BjörnPollex! –

Cuestiones relacionadas