ПРОБЛЕМА ВЫЯВЛЕНА, ОБНОВЛЕНА ОПУБЛИКОВАНА (прокрутите вниз)
Я разрабатываю настольное приложение, в настоящее время использующее Spring (spring-context
, 4.1.6.RELEASE
) для IoC и внедрения зависимостей. Я использую конфигурацию аннотации, используя @ComponentScan
. Проблема, с которой я столкнулся, должна быть реализована как функция в 4.X.X
, как указано здесь и здесь, но я я получаю старое исключение 3.X.X
.
У меня есть параметризованный интерфейс, представляющий общий репозиторий:
public interface DomainRepository<T> {
T add(T entity) throws ServiceException, IllegalArgumentException;
// ...etc
}
Затем у меня есть две конкретные реализации этого, ChunkRepositoryImpl
и ProjectRepositoryImpl
, которые параметризованы соответственно. Они имеют общую реализацию из абстрактного класса, но объявлены так:
@Repository
public class ChunkRepositoryImpl extends AbstractRepositoryImpl<Chunk> implements DomainRepository<Chunk> {
// ...+ various method implementations
}
@Repository
public class ProjectRepositoryImpl extends AbstractRepositoryImpl<Project> implements DomainRepository<Project> {
// ...+ various method implementations
}
Понимание приведенных выше ссылок приводит меня к мысли, что я смогу автоматически подключать их без необходимости вручную указывать bean-компоненты через @Qualifier
. Однако когда я это сделаю:
@Autowired
private DomainRepository<Project> repository;
Я получаю следующее исключение (которому, конечно же, предшествует длинная трассировка стека):
Вызвано: org.springframework.beans.factory.NoUniqueBeanDefinitionException: не определен квалифицирующий bean-компонент типа [com.foo.bar.repositories.DomainRepository]: ожидаемый единственный соответствующий bean-компонент, но найдено 2: chunkRepositoryImpl, projectRepositoryImpl
Может ли кто-нибудь пролить свет на то, почему это могло происходить? Я бы ожидал этого исключения в 3.X.X
, но этого не должно происходить в 4.X.X
. В чем разница между моей ситуацией и описанной здесь?
ОБНОВЛЕНИЕ
Я обнаружил источник проблемы. Один из методов в моем DomainRepository<T>
интерфейсе отмечен как @Async
и использует асинхронные возможности Spring. Удаление этого означает, что бобы правильно квалифицированы. Я предполагаю, что Spring преобразует классы с @Async
методами под капотом в какой-то другой класс, и этот процесс удаляет информацию о типе, что означает, что он не может отличить bean-компоненты.
Это означает, что теперь у меня есть два вопроса:
- Это предполагаемое поведение?
- Кто-нибудь может предложить обходной путь?
Вот проект, демонстрирующий проблему. Просто удалите аннотацию @Async
из интерфейса DomainRepository<T>
, и проблема исчезнет.
Project
в классе с полемrepository
? - person Sotirios Delimanolis   schedule 07.10.2015repository
определенно ссылается на тот же объект домена, что и объявление репозитория. - person Will Faithfull   schedule 07.10.2015@Async
. Без этой аннотации он работает должным образом. С, это не сработает с вышеуказанным. - person Will Faithfull   schedule 07.10.2015