Inyección de métodos con Spring
¿Cómo trabajar cuando necesitamos que una clase singleton tenga inyectada una clase prototype?.
La situación
La clase ImperioIrken está declarada como un Singleton. La clase Invasion, inyectada como dependencia, es stateful y por ello queremos que tenga el comportamiento de un Prototype:
<beans>
<bean id="imperioIrken" class="ejemplo.ImperioIrken"> <property name="invasion" ref="invasion"/> </bean>
<bean id="invasion" class="ejemplo.Invasion" scope="prototype"/>
</beans>
El problema
La clase ImperioIrken es un singleton, por lo tanto la factory de spring la instancia sólo una vez y le inyecta una instancia de la clase Invasion. Luego, todas las veces que usemos ImperioIrken nos retorna la única instancia existente de la clase. Y por ello no se crean nuevas instancias de la clase Invasion a pesar de que el bean tiene seteado el scope prototype.
La solución: Lookup method injection
Spring nos provee como solución definir en la clase singleton un método abstracto para la creación de los beans de la clase stateful (el método abstracto será implementado dinámicamente).
public abstract class ImperioIrken {
public Object process() { Invasion invasion = instanciarInvasion(); // continuamos con la lógica...
}
protected abstract Invasion instanciarInvasion();
}
En el archivo de definición de beans usamos el tag lookup-method, para lograr obtener una instancia nueva de la clase Invasion cada vez:
<beans>
<bean id="imperioIrken" class="ejemplo.ImperioIrken"> <lookup-method name="instanciarInvasion" bean="invasion"/> </bean>
<bean id="invasion" class="ejemplo.Invasion" scope="prototype"/>
</beans>