7

Я пытаюсь использовать @Autowired аннотации с моим общим интерфейсом Dao, как это:Spring 3 DI с использованием универсального интерфейса DAO

public interface DaoContainer<E extends DomainObject> { 
    public int numberOfItems(); 
    // Other methods omitted for brevity 
} 

Я использую этот интерфейс в моем контроллере в следующем виде:

@Configurable 
public class HelloWorld { 
    @Autowired 
    private DaoContainer<Notification> notificationContainer; 

    @Autowired 
    private DaoContainer<User> userContainer; 

    // Implementation omitted for brevity 
} 

Я настроил свой контекст приложения с следующей конфигурацией

<context:spring-configured /> 
<context:component-scan base-package="com.organization.sample"> 
<context:exclude-filter expression="org.springframework.stereotype.Controller" 
    type="annotation" /> 
</context:component-scan> 
<tx:annotation-driven /> 

Это работает только partiall y, поскольку Spring создает и вводит только один экземпляр моего DaoContainer, а именно DaoContainer. Другими словами, если я попрошу userContainer.numberOfItems(); Я получаю количество notificationContainer.numberOfItems()

Я пытался использовать строго типизированные интерфейсы, чтобы отметить правильное выполнение так:

public interface NotificationContainer extends DaoContainer<Notification> { } 
public interface UserContainer extends DaoContainer<User> { } 

А затем использовал эти интерфейсы, как это:

@Configurable 
public class HelloWorld { 
    @Autowired 
    private NotificationContainer notificationContainer; 
    @Autowired 
    private UserContainer userContainer; 
    // Implementation omitted... 
} 

к сожалению, это не в BeanCreationException:

org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.organization.sample.dao.NotificationContainer com.organization.sample.HelloWorld.notificationContainer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.organization.sample.NotificationContainer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

Теперь, Я немного запутался, как мне следует продолжить или использовать несколько Дао. Любая помощь будет принята с благодарностью :)

+0

Я не вижу классов реализации для ваших интерфейсов. Сколько их там, и на что они похожи? – skaffman

+0

У меня не было явных реализаций для интерфейсов, так как я надеялся, что могу использовать общий класс dao (т. Е. DaoContainer ). Я мог бы создать явные реализации (как указал Эспен в своем ответе). Это просто не кажется разумным, так как я стараюсь как можно больше использовать Java-дженерики. Однако у меня есть DaoContainerImpl . – Peders

+0

возможно http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/511417#511417 - это решение –

ответ

0

Можно автоположить столько фасолей, сколько пожелаете.

Но когда вы используете автопостроение по типу, это может быть только один компонент из каждого интерфейса. В сообщении об ошибке указано, что в контейнере Spring данного интерфейса нет ни одного компонента.

Решение:

отсутствующих реализаций DAO:

@Repository 
public class NotificationContainerImpl implements NotificationContainer {} 

@Repository 
public class UserContainerImpl implements UserContainer {} 

Ваш класс обслуживания:

@Service 
public class HelloWorld { 
    @Autowired 
    private NotificationContainer notificationContainer; 
    @Autowired 
    private UserContainer userContainer; 
    // Implementation omitted... 
} 

Я заменил @Configurable аннотацию с @Service. @Configurable используется вместе с AspectJ и не то, что вы хотите здесь. Вы должны использовать @Component или его специализацию, как @Service.

Также помните, что у вас есть все ваши компоненты Spring в вашем пакете com.organization.sample, чтобы контейнер Spring мог их найти.

Надеюсь, это поможет!

2

Хорошо, я думаю, что нашел довольно разумное решение для этой головоломки. Одним из способов решения этой проблемы было бы создание интерфейса и реализаций для каждого объекта в моей модели домена (как указывал Эспен в своем ответе ранее). Теперь рассмотрим наличие сотен объектов и, соответственно, сотен реализаций. Это было бы неправильно, не так ли?

Я отбрасываю сильно типизированный суб-интерфейсы, и я использую общий интерфейс вместо:

@Service // Using @Service annotation instead @Configurable as Espen pointed out 
public class HelloWorld { 
    @Autowired 
    private DaoContainer<Notification> notificationContainer; 

    @Autowired 
    private DaoContainer<User> userContainer; 

    // Implementation omitted 
} 

Реализация моего DaoContainer интерфейс будет выглядеть примерно так:

@Repository 
public class DaoContainerImpl<E extends DomainObject> implements DaoContainer<E> { 

    // This is something I need in my application logic 
    protected Class<E> type; 

    public int getNumberOfItems() { 
     // implementation omitted 
    } 
    // getters and setters for fields omitted 

} 

И, наконец, приложение контексте:

<context:spring-configured /> 
<context:component-scan base-package="com.organization.sample"> 
<context:exclude-filter expression="org.springframework.stereotype.Controller" 
    type="annotation" /> 
</context:component-scan> 

<bean class="com.organization.sample.dao.DaoContainerImpl" id="userContainer"> 
    <property name="type" value="com.organization.sample.domain.DiaryUser" /> 
</bean> 
<bean class="com.organization.sample.dao.DaoContainerImpl" id="notificationContainer"> 
    <property name="type" value="com.organization.sample.domain.DiaryNotification" /> 
</bean> 

Так что в принципе я не мог получить чистое автоустройство для работы, но это решение работает для меня (по крайней мере пока) :)

+0

Я знаю, что это старая проблема, но ваше решение очень похоже на использование маркера интерфейсов, как описано в http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/503011#503011. Я полагаю, что это связано с личным предпочтением загрязнять либо конфигурационный файл Spring, либо дерево исходных текстов java. –

Смежные вопросы