Среда тестирования Spring и основанная на аннотации проблема автопроводного соединения

Я хотел бы использовать две различных реализации для ДАО с 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;

но ошибка сохраняется.

Два вопроса:

  1. Как эта проблема может быть решена с основанной на аннотации конфигурацией?
  2. Как я могу запустить тесты, не автосоединяя проводом и аннотации?
5
задан Ta Sas 8 July 2010 в 03:59
поделиться

4 ответа

Вы используете бобы без имен, поэтому Spring попытается придумать имя, это имя может быть основано на аннотации @Component, которую вы предположительно имеете на вашем классе, но это также может быть верблюжья версия вашего неквалифицированного имени класса вашего боба (в обоих случаях они получатся одинаковыми, что вызовет возражение Spring).

Также, похоже, вы смешиваете сканирование компонентов и xml-конфигурацию, что выглядит немного странно, на мой взгляд.

Есть много способов выйти из этого положения, но наиболее чистым является использование только одного боба, реализующего контракт, который вы пытаетесь выполнить. Если вам нужны разные реализации, вы должны дать им разные и более описательные имена:

<bean id="jpaUserRepository" class="..JpaUserRepository"/>

Это даст вам более полезное протоколирование, даже если имена бобов никогда не используются, потому что вы полагаетесь на автоматическое подключение.

2
ответ дан 15 December 2019 в 06:13
поделиться

Вы можете попробовать внедрить зависимость по имени, используя аннотацию @Resource. Вам придется дать имена (id) бобам или использовать значение по умолчанию, которое представляет собой незаглавное неквалифицированное имя класса.

0
ответ дан 15 December 2019 в 06:13
поделиться
  1. Сделайте то, что предложил Ивейн: лучше назовите классы реализации (например, HibernateUserDao и JpaUserDao); или укажите уникальное имя bean-компонента через аннотацию @Component или @Repository в ваших классах реализации UserDAO.
  2. В настоящее время вы не можете запускать тесты без автоподключения. Подробнее см. В этой проблеме JIRA: https://jira.springsource.org/browse/SPR-6050

С уважением,

Сэм (автор Spring TestContext Framework)

p.s. Нет, проблема, с которой вы столкнулись, не связана с SPR-4524.

1
ответ дан 15 December 2019 в 06:13
поделиться

Теперь у меня все работает! Однако я не думаю, что это лучшая практика. Я просто исключил путь нежелательных 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 ?

0
ответ дан 15 December 2019 в 06:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: