2011-01-03 14 views
9

Hemos decidido utilizar Dependency Injection con anotaciones JSR-330 para nuestros futuros esfuerzos de modularización, y hemos estado muy satisfechos con el primer entregable basado en Guice 2 SVN.¿Cómo configuro JSR-330 @Provider y @Inject @Named ("foo") Cadena ** programáticamente ** en Spring?

Ahora tenemos que asegurar y documentar mediante pruebas unitarias que las construcciones que necesitamos también funcionan en Spring cuando se configuran programáticamente (queremos el mismo soporte de refactorización que con Guice para que no haya archivos XML). Tengo problemas con @Provider y @Inject @Named("foo") String pero he dejado claro @Inject trabajo con:

ApplicationContext ctx = new AnnotationConfigApplicationContext(LIBL_Object.class, 
                   CORE_Provider.class); 
this.object = ctx.getBean(LIBL_Object.class); 

donde LIBL_Object es la clase base a inyectar en , pero el CORE_Provider no se registra como esperaba dentro de la primavera.

La implementación de CORE_Provider es

package qa.jsr330.core; 

import javax.inject.Provider; 

public class CORE_Provider implements Provider<ProvidedInterface> { 
    @Override 
    public ProvidedInterface get() { 
     return new CORE_Provided(); 
    } 
} 

y quiero que se inyecta en

package qa.jsr330.core; 

import javax.inject.Inject; 

public class LIBL_Object { 

    private ProvidedInterface provided; 

    public ProvidedInterface getProvided() { 
     return provided; 
    } 

    @Inject 
    public void setProvided(ProvidedInterface provided) { 
     this.provided = provided; 
    } 
// Other stuff omitted. 
} 

También hemos encontrado que podemos pasar valores de configuración muy claramente el uso de la etiqueta @Named. Este código es el siguiente:

String hostname; 
@Inject 
public void setHostname(@Named("as400.hostname") String hostname) { 
    this.hostname = hostname; 
} 

en el que deberá volver a registrar esta cadena con Guice usando

bindConstant().annotatedWith(Names.named("as400.hostname")).to(value); 

Así que las dos preguntas son:

  • ¿Cómo registrar la clase @Provider con la primavera 3 programáticamente?
  • ¿Cómo registro una constante de cadena con Spring 3 para que @Named la seleccione correctamente?

Respuesta

5

La respuesta corta es: no hay tal cosa como la configuración programática de Spring.

A pesar del hecho de que tanto Spring como Guice admiten JSR-330 API y que Spring se puede configurar sin XML ahora, sus ideologías son todavía muy diferentes. Spring se basa en la configuración estática, ya sea en forma de archivos XML o clases de Java anotadas. Por lo tanto, un intento directo de adaptar la configuración estilo Guice a Spring puede generar dificultades.

En cuanto al problema con Provider - Spring no soporta javax.inject.Provider de la misma manera como toProvider() unión en Guice (por cierto, este uso de Provider no se especifica en JSR-330 docs). Por lo tanto pueden ser necesarias algunas anotaciones-Spring específico, por ejemplo

@Configuration 
public class CORE_Provider implements Provider<ProvidedInterface> { 
     @Override @Bean 
     public ProvidedInterface get() { 
      return new CORE_Provided(); 
     } 
} 

valor Binding procedente del exterior puede ser difícil debido a la naturaleza estática de la configuración del resorte. Por ejemplo, en su caso, se puede hacer así:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
ctx.register(IBL_Object.class); 
ctx.register(CORE_Provider.class); 
ctx.registerBeanDefinition("as400.hostname", 
    BeanDefinitionBuilder.rootBeanDefinition(String.class) 
     .addConstructorArgValue(value).getBeanDefinition()); 
ctx.refresh(); 
+1

¡Gracias! La inyección de "as400.hostname" funciona, lo cual es genial, pero la subclase CORE_Provider que he escrito con las anotaciones que sugiere no se recoge (pero puedo registrar una instancia de la interfaz, que luego se inyecta). Obtengo la excepción "No matching bean of type ..." de Spring. ¿Qué polvo de duende me estoy perdiendo? –

+0

> no existe la configuración programática de Spring ... No estoy seguro de lo que quiere decir con "programática", pero su código de ejemplo donde configura el AnnotationConfigApplicationContext de Java me parece programático. –

Cuestiones relacionadas