2011-06-03 11 views
8

En Guice 2 o 3, existe la denominada Inyección asistida/parcial descrita here. Con esto, Guice sintetiza la implementación de fábrica (implementando mi interfaz) para mi objeto y algunos de los argumentos constructor son inyectados por Guice, y algunos se proporcionan desde el contexto .¿Es posible y cómo hacer la inyección asistida en primavera?

¿Es posible y cómo hacer lo mismo con Spring?

+1

Esta pregunta es bastante antigua. ¿Ha cambiado algo con respecto a esto en primavera? Esto suena como una solicitud de función razonable (¿no?) – theadam

Respuesta

7

Lo siguiente hace exactamente lo que solicité. Sin embargo, no sintetiza la implementación de la fábrica, es lo suficientemente bueno ya que la fábrica tiene acceso al contexto de inyección para que pueda usar otros frijoles (artefactos inyectables) durante la construcción. Utiliza Java basado en @Configuration en lugar de XML, pero también funcionará con XML.

La interfaz de fábrica:

public interface Robot { 

} 

// Implementation of this is to be injected by the IoC in the Robot instances 
public interface Brain { 
    String think(); 
} 

public class RobotImpl implements Robot { 

    private final String name_; 
    private final Brain brain_; 

    @Inject 
    public RobotImpl(String name, Brain brain) { 
     name_ = name; 
     brain_ = brain; 
    } 

    public String toString() { 
     return "RobotImpl [name_=" + name_ + "] thinks about " + brain_.think(); 
    } 
} 

public class RobotBrain implements Brain { 
    public String think() { 
     return "an idea"; 
    } 
} 


// The assisted factory type 
public interface RobotFactory { 
    Robot newRobot(String name); 
} 

// esta es la configuración de la primavera que muestra cómo hacer la inyección asistida

@Configuration 
class RobotConfig { 

    @Bean @Scope(SCOPE_PROTOTYPE) 
    public RobotFactory robotFactory() { 
     return new RobotFactory() { 

      @Override 
      public Robot newRobot(String name) { 
       return new RobotImpl(name, r2dxBrain()); 
      } 
     }; 
    } 

    @Bean @Scope(SCOPE_PROTOTYPE) 
    public Brain r2dxBrain() { 
     return new RobotBrain(); 
    } 
} 

El código de prueba:

public class RobotTest { 

    @Test 
    public void t1() throws Exception { 
     ApplicationContext ctx = new 
          AnnotationConfigApplicationContext(RobotConfig.class); 
     RobotFactory rf = ctx.getBean(RobotFactory.class); 
     assertThat(rf.newRobot("R2D2").toString(), 
      equalTo("RobotImpl [name_=R2D2] thins about an idea")); 
    } 

} 

Esto logra exactamente lo que hace Guice. La diferencia difícil es el Scope. El alcance predeterminado de Spring es Singleton y Guice's is not (es prototipo).

4

AFAIK usted no puede. En primavera puede tener Instantiation using a static factory method o Instantiation using an instance factory method. Con la segunda opción, puede definir un bean myFactoryBean trabajando como fábrica para otro bean. También puede pasar los argumentos de construcción al myFactoryBean utilizando constructor-arg (consulte, por ejemplo, la sección Using An Instance Factory Method on this blog), que le proporciona el equivalente de los argumentos Guice-Injected. Sin embargo, no sé de ninguna manera para proporcionar argumentos adicionales del contexto al invocar el método de fábrica.

+1

Creo que puedes hacerlo en 3.0 con Spring-EL, pero está empezando a sentirse realmente desagradable. –

Cuestiones relacionadas