Tengo un conjunto de clases con un complejo esquema de inicialización. Básicamente, comienzo con la interfaz que necesito controlar, y luego hago un montón de llamadas, y termino con un objeto que implementa esa interfaz.Spring @Autowiring con beans genéricos fabricados en fábrica
Con el fin de manejar esto, hice una clase de fábrica que puede, dada una interfaz, producir el objeto final. Hice esta fábrica en un frijol, y en XML especifiqué mis varios beans de servicio como instanciados a través de este objeto de fábrica con un parámetro de la interfaz que implementarán.
Esto funciona muy bien, y obtengo exactamente los granos que necesito. Desafortunadamente, me gustaría acceder a ellos desde mis clases de controlador, que se descubren a través del escaneo de componentes. Utilizo @Autowired aquí, y parece que Spring no tiene idea de qué tipo de objeto son estos, y como @Autowired funciona por tipo, soy SOL.
Usar @Resource (name = "beanName") aquí funcionaría perfectamente, sin embargo, parece extraño usar @Resource para algunos beans y @Autowired para otros.
¿Hay alguna manera de que Spring sepa qué interfaz creará la fábrica para cada uno de estos beans sin tener un método de fábrica diferente para cada tipo?
Estoy usando Spring 2.5.6, por cierto, de lo contrario, solo me gustaría JavaConfig todo y olvidarse de él.
clase de fábrica:
<T extends Client> T buildService(Class<T> clientClass) {
//Do lots of stuff with client class and return an object of clientClass.
}
contexto de aplicaciones:
<bean id="serviceFactoryBean" class="com.captainAwesomePants.FancyFactory" />
<bean id="userService" factory-bean="serviceFactoryBean" factory-method="buildService">
<constructor-arg value="com.captain.services.UserServiceInterface" />
</bean>
<bean id="scoreService" factory-bean="serviceFactoryBean" factory-method="buildService">
<constructor-arg value="com.captain.services.ScoreServiceInterface" />
</bean>
mi controlador:
public class HomepageController {
//This doesn't work
@Autowired @Qualifier("userService") UserServiceInterface userService;
//This does
@Resource(name="scoreService") ScoreServiceInterface scoreService;
}
Me gusta. Me estaba alejando de FactoryBeans al principio, pero sinceramente parece que harán exactamente lo que yo quiero que hagan. –
@CaptainAwesomePants: tiendo a mantener mis implementaciones 'FactoryBean' tan delgadas como sea posible, haciéndolas delegar a otra clase que no usa Spring API. Usted podría hacer lo mismo: simplemente delegue en su 'serviceFactoryBean' existente. – skaffman
@skaffman: Entonces, en este caso, debe haber tantas implementaciones 'FactoryBean' como número de variaciones de tipos de devolución. Will Spring realizará el descubrimiento de tipo correcto si se agregan dos métodos adicionales a la fábrica 'UserServiceInterface buildUserService() {return buildService (UserServiceInterface.class); } 'y' ScoreServiceInterface buildScoreService() {return buildService (ScoreServiceInterface.class); } '(y el contexto se vuelve a sintonizar para usarlos)? –