Usando Spring Config de Java, necesito adquirir / instanciar un bean de ámbito prototipo con argumentos de constructor que solo se pueden obtener en tiempo de ejecución. Considere el siguiente ejemplo de código (simplificado por brevedad):
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
donde la clase Thing se define de la siguiente manera:
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
El aviso name
es final
: solo se puede suministrar a través de un constructor y garantiza la inmutabilidad. Las otras dependencias son dependencias específicas de la implementación de la Thing
clase, y no deben conocerse (estrechamente relacionadas) con la implementación del controlador de solicitudes.
Este código funciona perfectamente con la configuración Spring XML, por ejemplo:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
¿Cómo logro lo mismo con la configuración de Java? Lo siguiente no funciona con Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Ahora, podría crear una Fábrica, por ejemplo:
public interface ThingFactory {
public Thing createThing(String name);
}
Pero eso invalida el punto de usar Spring para reemplazar el patrón de diseño ServiceLocator y Factory , lo que sería ideal para este caso de uso.
Si Spring Java Config pudiera hacer esto, podría evitar:
- definir una interfaz de fábrica
- definir una implementación de Factory
- escribir pruebas para la implementación de Factory
Eso es un montón de trabajo (relativamente hablando) para algo tan trivial que Spring ya admite a través de la configuración XML.
Thing
implementación es en realidad más compleja y tiene dependencias de otros beans (simplemente los omití por brevedad). Como tal, no quiero que la implementación del controlador de Solicitud sepa sobre ellos, ya que esto acoplaría estrechamente el controlador a las API / beans que no necesita. Actualizaré la pregunta para reflejar su pregunta (excelente).
@Qualifier
parámetros a un setter @Autowired
en el setter.
@Bean
obras. Se @Bean
llama al método con los argumentos apropiados a los que pasó getBean(..)
.