Sfondo:
Ho un'applicazione Spring 2.5 / Java / Tomcat. C'è il seguente bean, che viene utilizzato in tutta l'applicazione in molti punti
public class HibernateDeviceDao implements DeviceDao
e il seguente bean che è nuovo:
public class JdbcDeviceDao implements DeviceDao
Il primo bean è configurato in questo modo (tutti i bean nel pacchetto sono inclusi)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
Il secondo (nuovo) bean è configurato separatamente
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
Ciò comporta (ovviamente) un'eccezione all'avvio del server:
l'eccezione nidificata è org.springframework.beans.factory.NoSuchBeanDefinitionException: nessun bean univoco di tipo [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] è definito: bean di corrispondenza singolo previsto ma trovato 2: [deviceDao, jdbcDeviceDao]
da una classe che cerca di autorizzare il bean in questo modo
@Autowired
private DeviceDao hibernateDevicDao;
perché ci sono due bean che implementano la stessa interfaccia.
La domanda:
È possibile configurare i bean in modo che
1. Non devo apportare modifiche alle classi esistenti, che hanno già l' HibernateDeviceDao
autowired
2. essere ancora in grado di usare il secondo (nuovo) bean in questo modo:
@Autowired
@Qualifier("jdbcDeviceDao")
Cioè avrei bisogno di un modo per configurare il HibernateDeviceDao
bean come bean predefinito da autowired, consentendo contemporaneamente l'uso di un the JdbcDeviceDao
quando lo specifica esplicitamente con l' @Qualifier
annotazione.
Quello che ho già provato:
Ho provato a impostare la proprietà
autowire-candidate="false"
nella configurazione bean per JdbcDeviceDao:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
perché lo dice la documentazione di primavera
Indica se questo bean deve essere preso in considerazione quando si cercano candidati corrispondenti per soddisfare i requisiti di autowiring di un altro bean. Si noti che ciò non influisce sui riferimenti espliciti per nome, che verranno risolti anche se il bean specificato non è contrassegnato come candidato autowire. *
che ho interpretato nel senso che potrei ancora autowire JdbcDeviceDao
usando l' @Qualifier
annotazione e avere HibernateDeviceDao
come bean predefinito. Apparentemente la mia interpretazione non è stata corretta, tuttavia, poiché si verifica il seguente messaggio di errore all'avvio del server:
Dipendenza insoddisfatta del tipo [class com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: previsto almeno 1 bean corrispondente
proveniente dalla classe in cui ho provato ad autorizzare il bean con un qualificatore:
@Autowired
@Qualifier("jdbcDeviceDao")
Soluzione:
Il suggerimento di skaffman di provare l'annotazione @Resource ha funzionato. Quindi la configurazione ha autowire-candidate impostato su false per jdbcDeviceDao e quando uso jdbcDeviceDao mi riferisco ad esso usando l'annotazione @Resource (invece di @Qualifier):
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;