Hintergrund:
Ich habe eine Spring 2.5 / Java / Tomcat-Anwendung. Es gibt die folgende Bohne, die an vielen Stellen in der gesamten Anwendung verwendet wird
public class HibernateDeviceDao implements DeviceDao
und die folgende Bohne, die neu ist:
public class JdbcDeviceDao implements DeviceDao
Die erste Bean ist so konfiguriert (alle Beans im Paket sind enthalten).
<context:component-scan base-package="com.initech.service.dao.hibernate" />
Die zweite (neue) Bean wird separat konfiguriert
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
Dies führt (natürlich) zu einer Ausnahme beim Starten des Servers:
verschachtelte Ausnahme ist org.springframework.beans.factory.NoSuchBeanDefinitionException: Es ist keine eindeutige Bean vom Typ [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] definiert: erwartete einzelne übereinstimmende Bean, aber gefunden 2: [deviceDao, jdbcDeviceDao]
von einer Klasse, die versucht, die Bohne so automatisch zu verdrahten
@Autowired
private DeviceDao hibernateDevicDao;
weil es zwei Beans gibt, die dieselbe Schnittstelle implementieren.
Die Frage:
Ist es möglich, die Beans so zu konfigurieren?
1. Ich muss keine Änderungen an vorhandenen Klassen vornehmen, die bereits über eine HibernateDeviceDao
automatische Verdrahtung verfügen
2. die zweite (neue) Bohne immer noch so verwenden können:
@Autowired
@Qualifier("jdbcDeviceDao")
Das heißt, ich würde eine Möglichkeit benötigen, die HibernateDeviceDao
Bean als Standard-Bean für die automatische Verdrahtung zu konfigurieren und gleichzeitig die Verwendung eines zu ermöglichen, JdbcDeviceDao
wenn dies explizit mit der @Qualifier
Anmerkung angegeben wird.
Was ich schon versucht habe:
Ich habe versucht, die Eigenschaft festzulegen
autowire-candidate="false"
in der Bean-Konfiguration für JdbcDeviceDao:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
weil die Spring-Dokumentation das sagt
Gibt an, ob diese Bean berücksichtigt werden soll, wenn nach passenden Kandidaten gesucht wird, um die Autowiring-Anforderungen einer anderen Bean zu erfüllen. Beachten Sie, dass dies keine Auswirkungen auf explizite Verweise nach Namen hat, die auch dann aufgelöst werden, wenn die angegebene Bean nicht als Autowire-Kandidat markiert ist. *
was ich so interpretierte, dass ich JdbcDeviceDao
mit der @Qualifier
Annotation immer noch automatisch verdrahten und die HibernateDeviceDao
als Standard-Bean haben konnte. Anscheinend war meine Interpretation jedoch nicht korrekt, da dies beim Starten des Servers zu der folgenden Fehlermeldung führt:
Unbefriedigte Abhängigkeit vom Typ [Klasse com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: mindestens 1 übereinstimmende Bean erwartet
Ich komme aus der Klasse, in der ich versucht habe, die Bohne mit einem Qualifier automatisch zu verdrahten:
@Autowired
@Qualifier("jdbcDeviceDao")
Lösung:
Der Vorschlag von skaffman, die @ Resource-Annotation auszuprobieren, hat funktioniert. In der Konfiguration ist der Autowire-Kandidat für jdbcDeviceDao auf false gesetzt, und wenn ich jdbcDeviceDao verwende, verweise ich mit der Annotation @Resource (anstelle von @Qualifier) darauf:
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;