7

Próbuję użyć @Autowired adnotacji z moim rodzajowego interfejsu Dao jak ten:Wiosna 3 DI użyciu rodzajowy interfejs DAO

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

używam tego interfejsu w moim kontrolera w następujący sposób:

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

    @Autowired 
    private DaoContainer<User> userContainer; 

    // Implementation omitted for brevity 
} 

mam skonfigurowane moje kontekstu aplikacji z następującej konfiguracji

<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 /> 

ta działa tylko partiall y, ponieważ Spring tworzy i wstrzykuje tylko jedną instancję mojego DaoContainer, mianowicie DaoContainer. Innymi słowy, jeśli zapytam userContainer.numberOfItems(); Mam liczbę notificationContainer.numberOfItems()

Próbowałem użyć silnie typami interfejsów zaznaczyć prawidłową realizację takiego:

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

a następnie wykorzystywane te interfejsy tak:

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

Niestety to nie 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)} 

teraz Jestem nieco zdezorientowany, w jaki sposób powinienem kontynuować, czy też używać wielu Dao, nawet możliwych. Jakakolwiek pomoc byłaby bardzo doceniana :)

+0

Nie widzę żadnych klas implementacji dla twoich interfejsów. Ile tam jest i jak one wyglądają? – skaffman

+0

Nie miałem jawnych implementacji dla interfejsów, ponieważ miałem nadzieję, że mogę użyć ogólnej klasy dao (to jest DaoContainer ). Mógłbym stworzyć wyraźne implementacje (jak zauważył Espen w swojej odpowiedzi). To po prostu nie wydaje się rozsądne, ponieważ staram się jak najwięcej wykorzystywać generyczne Java. Jednak mam DaoContainerImpl . – Peders

+0

może http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/511417#511417 jest rozwiązaniem –

Odpowiedz

0

Możliwe jest, aby wyposażyć tyle fasoli, ile chcesz.

Ale kiedy używasz autowiring według typu, może to być tylko jedna z fasoli każdego interfejsu. Twój komunikat o błędzie mówi, że nie masz dostępnego komponentu bean w kontenerze Spring danego interfejsu.

Rozwiązanie:

brakujące implementacje DAO:

@Repository 
public class NotificationContainerImpl implements NotificationContainer {} 

@Repository 
public class UserContainerImpl implements UserContainer {} 

Twój klasy usługi:

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

Wymieniłem @Configurable adnotacji z @Service. @Configurable jest używany razem z AspectJ i nie jest tym, czego potrzebujesz. Musisz użyć @Component lub specjalizacji takich jak @Service.

Pamiętaj też, aby wszystkie komponenty sprężynowe znajdowały się w pakiecie com.organization.sample, aby umożliwić znajdowanie kontenera Spring.

Mam nadzieję, że to pomoże!

2

Ok, myślę, że znalazłem dość rozsądne rozwiązanie tej zagadki. Jednym ze sposobów radzenia sobie z tym byłoby stworzenie interfejsu i implementacji dla każdej jednostki w moim modelu domeny (jak wskazał Espen w swojej wcześniejszej odpowiedzi). Rozważmy teraz setki podmiotów i odpowiednio setki wdrożeń. To nie byłoby w porządku, prawda?

mam wyrzucić silnie wpisane sub-interfejsy i używam rodzajowy interfejs zamiast:

@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 
} 

Realizacja dla mojego interfejsu DaoContainer będzie wyglądać mniej więcej tak:

@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 

} 

I wreszcie aplikacji kontekst:

<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> 

W zasadzie nie mogłem uzyskać czysty generyczny program do pracy, ale to rozwiązanie działa dla mnie (przynajmniej na razie) :)

+0

Wiem, że to stary problem, ale twoje rozwiązanie jest dość podobne do używania znacznika interfejsy opisane w http://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type/503011#503011. Przypuszczam, że przychodzi do osobistych preferencji, aby zanieczyścić plik konfiguracyjny Spring lub drzewo źródłowe java. –

Powiązane problemy