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 HibernateDeviceDao
autowired
2. todavía poder usar el segundo (nuevo) bean como este:
@Autowired
@Qualifier("jdbcDeviceDao")
Es decir, necesitaría una forma de configurar el HibernateDeviceDao
bean como el bean predeterminado que se conectará automáticamente, permitiendo simultáneamente el uso de un JdbcDeviceDao
cuando se especifique explícitamente con la @Qualifier
anotació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 JdbcDeviceDao
usando la @Qualifier
anotación y tener el HibernateDeviceDao
bean 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;