Я хотел бы использовать две различных реализации для ДАО с testframework Spring.
src.main.java
.businessobjects
\-User.java
.dao
\-IUserDAO.java
.daojpa
\-UserDAO.java
.daohibernate
\-UserDAO.java
Пружинный тестовый сценарий в:
src.test.java.base:
package base;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/hibernate-beans.xml")
@Transactional
public abstract class SpringTestCase {}
И вот ошибка:
Вызванный: java.lang. IllegalStateException: указанный аннотацией боб называет 'userDAO' для класса компонента [jpadao. UserDAO] конфликтует с существующим, несовместимым бобовым определением того же имени и класса [jpaadao. UserDAO]
Я уже попытался переопределить автопроводное соединение при помощи спецификаторов, например:
<bean class="jpaadao.UserDAO">
<qualifier value="jpaa"/>
</bean>
<bean class="jpadao.UserDAO">
<qualifier value="jpa"/>
</bean>
И затем в проводном соединении тестового сценария с
@Autowired
@Qualifier("jpa")
private IUserDAO userDAO;
но ошибка сохраняется.
Два вопроса:
Вы используете бобы без имен, поэтому Spring попытается придумать имя, это имя может быть основано на аннотации @Component, которую вы предположительно имеете на вашем классе, но это также может быть верблюжья версия вашего неквалифицированного имени класса вашего боба (в обоих случаях они получатся одинаковыми, что вызовет возражение Spring).
Также, похоже, вы смешиваете сканирование компонентов и xml-конфигурацию, что выглядит немного странно, на мой взгляд.
Есть много способов выйти из этого положения, но наиболее чистым является использование только одного боба, реализующего контракт, который вы пытаетесь выполнить. Если вам нужны разные реализации, вы должны дать им разные и более описательные имена:
<bean id="jpaUserRepository" class="..JpaUserRepository"/>
Это даст вам более полезное протоколирование, даже если имена бобов никогда не используются, потому что вы полагаетесь на автоматическое подключение.
Вы можете попробовать внедрить зависимость по имени, используя аннотацию @Resource
. Вам придется дать имена (id) бобам или использовать значение по умолчанию, которое представляет собой незаглавное неквалифицированное имя класса.
С уважением,
Сэм (автор Spring TestContext Framework)
p.s. Нет, проблема, с которой вы столкнулись, не связана с SPR-4524.
Теперь у меня все работает! Однако я не думаю, что это лучшая практика. Я просто исключил путь нежелательных DAO, написав в appContext.xml:
<context:component-scan base-package="test">
<context:exclude-filter type="regex" expression="test\.daohibernate.*"></context:exclude-filter>
</context:component-scan>
Есть предложения? Может ли эта проблема быть связана с http://jira.springframework.org/browse/SPR-4524 ?