История:
У меня есть приложение Spring 2.5/Java/Tomcat. Существует следующий bean, который используется во всем приложении во многих местах
public class HibernateDeviceDao implements DeviceDao
и следующий bean, который является новым:
public class JdbcDeviceDao implements DeviceDao
Первый bean настроен так (все beans в пакете включены)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
Второй (новый) bean настроен отдельно
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
Это приводит (конечно) к исключению при запуске сервера:
Вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: не определено уникальное bean типа [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao]: ожидаемое одиночное соответствие bean, но найдено 2: [deviceDao, jdbcDeviceDao]
из класса, пытающегося autwire bean, как этот
@Autowired
private DeviceDao hibernateDevicDao;
потому что существует два beans, реализующих один и тот же интерфейс.
Вопрос:
Можно ли настроить beans так, чтобы
1. Мне не нужно вносить изменения в существующие классы, у которых уже есть HibernateDeviceDao
autowired
2. все еще может использовать второй (новый) bean следующим образом:
@Autowired
@Qualifier("jdbcDeviceDao")
т.е. мне понадобится способ настройки HibernateDeviceDao
bean, поскольку по умолчанию bean должен быть автообновлен, одновременно позволяя использовать JdbcDeviceDao
, явно указывая это с помощью аннотации @Qualifier
.
Что я уже пробовал:
Я попытался установить свойство
autowire-candidate="false"
в конфигурации bean для JdbcDeviceDao:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
поскольку документация Spring гласит, что
Указывает, следует ли учитывать этот bean, если поиск подходящих кандидатов для удовлетворения других bean требования автоувеличивания. Обратите внимание, что это не влияет на явное ссылки по имени, которые будут решены, даже если указанные bean не помечен как кандидат на автоспуск. *
который я интерпретировал как означающий, что я мог бы autwire JdbcDeviceDao
использовать аннотацию @Qualifier
и иметь HibernateDeviceDao
по умолчанию bean. По-видимому, моя интерпретация была неправильной, так как это приводит к появлению следующего сообщения об ошибке при запуске сервера:
Неудовлетворительная зависимость типа [класс com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: ожидается как минимум 1 совпадение bean
входящий в класс, где я пробовал autowiring bean с квалификатором:
@Autowired
@Qualifier("jdbcDeviceDao")
Решение:
skaffman's , чтобы попробовать аннотацию @Resource. Таким образом, у конфигурации есть параметр autowire-кандидат, установленный в false для jdbcDeviceDao, и при использовании jdbcDeviceDao я ссылаюсь на него с помощью аннотации @Resource (вместо @Qualifier):
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;