Antecedentes:
Tengo una aplicación Spring 2.5 / Java / Tomcat. Existe el siguiente bean, que se utiliza en toda la aplicación en muchos lugares.
public class HibernateDeviceDao implements DeviceDao
y el siguiente bean que es nuevo:
public class JdbcDeviceDao implements DeviceDao
El primer bean está configurado de esta manera (todos los beans en el paquete están incluidos)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
El segundo bean (nuevo) se configura por separado
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
Esto resulta (por supuesto) en una excepción al iniciar el servidor:
la excepción anidada es org.springframework.beans.factory.NoSuchBeanDefinitionException: no se ha definido un bean único de tipo [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao]: bean coincidente único esperado pero encontrado 2: [deviceDao, jdbcDeviceDao]
de una clase que intenta conectar automáticamente el bean así
@Autowired
private DeviceDao hibernateDevicDao;
porque hay dos beans que implementan la misma interfaz.
La pregunta:
¿Es posible configurar los beans para que
1. No tengo que hacer cambios en las clases existentes, que ya tienen el HibernateDeviceDaoautowired
2. todavía poder usar el segundo (nuevo) bean como este:
@Autowired
@Qualifier("jdbcDeviceDao")
Es decir, necesitaría una forma de configurar el HibernateDeviceDaobean como el bean predeterminado que se conectará automáticamente, permitiendo simultáneamente el uso de un JdbcDeviceDaocuando se especifique explícitamente con la @Qualifieranotación.
Lo que ya he probado:
Traté de configurar la propiedad
autowire-candidate="false"
en la configuración de bean para JdbcDeviceDao:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
porque la documentación de Spring dice que
Indica si este bean debe considerarse o no cuando se buscan candidatos coincidentes para satisfacer los requisitos de cableado automático de otro bean. Tenga en cuenta que esto no afecta a las referencias explícitas por nombre, que se resolverán incluso si el bean especificado no está marcado como candidato de cableado automático. *
lo cual interpreté para significar que aún podía conectar automáticamente JdbcDeviceDaousando la @Qualifieranotación y tener el HibernateDeviceDaobean predeterminado. Aparentemente, mi interpretación no fue correcta, ya que esto da como resultado el siguiente mensaje de error al iniciar el servidor:
Dependencia insatisfecha del tipo [clase com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: esperaba al menos 1 bean coincidente
viniendo de la clase donde probé el cableado automático del bean con un calificador:
@Autowired
@Qualifier("jdbcDeviceDao")
Solución:
La sugerencia de skaffman de probar la anotación @Resource funcionó. Entonces, la configuración tiene autowire-candidato establecido en false para jdbcDeviceDao y cuando uso el jdbcDeviceDao me refiero a él usando la anotación @Resource (en lugar de @Qualifier):
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;